optimize events for IobCobCalculator

This commit is contained in:
Milos Kozak 2021-04-12 14:31:15 +02:00
parent aadeeeebbf
commit a6b67b2bb7
28 changed files with 135 additions and 241 deletions

View file

@ -26,13 +26,41 @@ class CompatDBHelper @Inject constructor(
rxBus.send(EventNewBG(null)) rxBus.send(EventNewBG(null))
} }
.subscribe { .subscribe {
it.filterIsInstance<GlucoseValue>().firstOrNull()?.let { /**
aapsLogger.debug(LTag.DATABASE, "Firing EventNewHistoryData") * GlucoseValues can come in batch
rxBus.send(EventNewHistoryData(it.timestamp)) * oldest one should be used for invalidation, newest one for for triggering Loop.
} * Thus we need to collect both
it.filterIsInstance<GlucoseValue>().lastOrNull()?.let { *
*/
var newestGlucoseValue : GlucoseValue? = null
it.filterIsInstance<GlucoseValue>().lastOrNull()?.let { gv ->
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg") aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg")
rxBus.send(EventNewBG(it)) rxBus.send(EventNewBG(gv))
newestGlucoseValue = gv
}
it.filterIsInstance<GlucoseValue>().map { gv -> gv.timestamp }.minOrNull()?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventNewHistoryData")
rxBus.send(EventNewHistoryData(timestamp, true, newestGlucoseValue))
}
it.filterIsInstance<Carbs>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventTreatmentChange")
rxBus.send(EventTreatmentChange())
rxBus.send(EventNewHistoryData(timestamp, false))
}
it.filterIsInstance<Bolus>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventTreatmentChange")
rxBus.send(EventTreatmentChange())
rxBus.send(EventNewHistoryData(timestamp, false))
}
it.filterIsInstance<TemporaryBasal>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventTempBasalChange")
rxBus.send(EventTempBasalChange())
rxBus.send(EventNewHistoryData(timestamp, false))
}
it.filterIsInstance<ExtendedBolus>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
aapsLogger.debug(LTag.DATABASE, "Firing EventExtendedBolusChange")
rxBus.send(EventExtendedBolusChange())
rxBus.send(EventNewHistoryData(timestamp, false))
} }
it.filterIsInstance<TemporaryTarget>().firstOrNull()?.let { it.filterIsInstance<TemporaryTarget>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventTempTargetChange") aapsLogger.debug(LTag.DATABASE, "Firing EventTempTargetChange")
@ -46,21 +74,5 @@ class CompatDBHelper @Inject constructor(
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged") aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventFoodDatabaseChanged()) rxBus.send(EventFoodDatabaseChanged())
} }
it.filterIsInstance<Carbs>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventTreatmentChange())
}
it.filterIsInstance<Bolus>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventTreatmentChange())
}
it.filterIsInstance<TemporaryBasal>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventTempBasalChange")
rxBus.send(EventTempBasalChange())
}
it.filterIsInstance<ExtendedBolus>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventExtendedBolusChange")
rxBus.send(EventExtendedBolusChange())
}
} }
} }

View file

@ -34,13 +34,9 @@ import javax.inject.Inject;
import info.nightscout.androidaps.dana.comm.RecordTypes; import info.nightscout.androidaps.dana.comm.RecordTypes;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
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;
import info.nightscout.androidaps.events.EventReloadTempBasalData;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface; import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.ProfileInterface;
@ -50,7 +46,6 @@ 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.general.openhumans.OpenHumansUploader; import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
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.PercentageSplitter; import info.nightscout.androidaps.utils.PercentageSplitter;
@ -73,10 +68,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
@Inject DateUtil dateUtil; @Inject DateUtil dateUtil;
public static final String DATABASE_NAME = "AndroidAPSDb"; public static final String DATABASE_NAME = "AndroidAPSDb";
public static final String DATABASE_EXTENDEDBOLUSES = "ExtendedBoluses";
public static final String DATABASE_DANARHISTORY = "DanaRHistory"; public static final String DATABASE_DANARHISTORY = "DanaRHistory";
public static final String DATABASE_DBREQUESTS = "DBRequests"; public static final String DATABASE_DBREQUESTS = "DBRequests";
public static final String DATABASE_TDDS = "TDDs";
private static final int DATABASE_VERSION = 13; private static final int DATABASE_VERSION = 13;

View file

@ -1,3 +0,0 @@
package info.nightscout.androidaps.events
class EventReloadTempBasalData : Event()

View file

@ -1,3 +0,0 @@
package info.nightscout.androidaps.events
class EventReloadTreatmentData(var next: Event) : Event()

View file

@ -23,7 +23,6 @@ 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.overview.OverviewMenus import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensBgLoaded
import info.nightscout.androidaps.events.EventAutosensCalculationFinished import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
@ -181,16 +180,6 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
} }
}, fabricPrivacy::logException) }, fabricPrivacy::logException)
) )
disposable.add(rxBus
.toObservable(EventAutosensBgLoaded::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({
// catch only events from iobCobCalculatorPluginHistory
if (it.cause is EventCustomCalculationFinished) {
updateGUI("EventAutosensCalculationFinished", bgOnly = true)
}
}, fabricPrivacy::logException)
)
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventIobCalculationProgress::class.java) .toObservable(EventIobCalculationProgress::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)

View file

@ -9,6 +9,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Food import info.nightscout.androidaps.database.entities.Food
import info.nightscout.androidaps.database.transactions.SyncNsFoodTransaction import info.nightscout.androidaps.database.transactions.SyncNsFoodTransaction
import info.nightscout.androidaps.extensions.foodFromJson
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
@ -16,7 +17,6 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.receivers.DataWorker import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.extensions.foodFromJson
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 org.json.JSONObject
@ -75,7 +75,7 @@ class FoodPlugin @Inject constructor(
isValid = false isValid = false
).also { it.interfaceIDs.nightscoutId = JsonHelper.safeGetString(jsonFood, "_id") } ).also { it.interfaceIDs.nightscoutId = JsonHelper.safeGetString(jsonFood, "_id") }
repository.runTransactionForResult(SyncNsFoodTransaction(delFood)) repository.runTransactionForResult(SyncNsFoodTransaction(delFood, true))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while removing food", it) aapsLogger.error(LTag.DATABASE, "Error while removing food", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -89,7 +89,7 @@ class FoodPlugin @Inject constructor(
else -> { else -> {
val food = foodFromJson(jsonFood) val food = foodFromJson(jsonFood)
if (food != null) { if (food != null) {
repository.runTransactionForResult(SyncNsFoodTransaction(food)) repository.runTransactionForResult(SyncNsFoodTransaction(food, false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while adding/updating food", it) aapsLogger.error(LTag.DATABASE, "Error while adding/updating food", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
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 info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -76,7 +77,10 @@ class MaintenanceFragment : DaggerFragment() {
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribeBy( .subscribeBy(
onError = { aapsLogger.error("Error clearing databases", it) }, onError = { aapsLogger.error("Error clearing databases", it) },
onComplete = { rxBus.send(EventNewBG(null)) } onComplete = {
rxBus.send(EventNewBG(null))
rxBus.send(EventNewHistoryData(0, true))
}
) )
) )
uel.log(Action.RESET_DATABASES, Sources.Maintenance) uel.log(Action.RESET_DATABASES, Sources.Maintenance)

View file

@ -41,7 +41,7 @@ class NSClientAddUpdateWorker(
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var buildHelper: BuildHelper @Inject lateinit var buildHelper: BuildHelper
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var dateutil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: ConfigInterface @Inject lateinit var config: ConfigInterface
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@Inject lateinit var databaseHelper: DatabaseHelperInterface @Inject lateinit var databaseHelper: DatabaseHelperInterface
@ -71,12 +71,12 @@ class NSClientAddUpdateWorker(
//Find latest date in treatment //Find latest date in treatment
val mills = safeGetLong(json, "mills") val mills = safeGetLong(json, "mills")
if (mills != 0L && mills < dateutil.now()) if (mills != 0L && mills < dateUtil.now())
if (mills > latestDateInReceivedData) latestDateInReceivedData = mills if (mills > latestDateInReceivedData) latestDateInReceivedData = mills
if (insulin > 0) { if (insulin > 0) {
bolusFromJson(json)?.let { bolus -> bolusFromJson(json)?.let { bolus ->
repository.runTransactionForResult(SyncNsBolusTransaction(bolus)) repository.runTransactionForResult(SyncNsBolusTransaction(bolus, invalidateByNsOnly = false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it) aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -105,7 +105,7 @@ class NSClientAddUpdateWorker(
} }
if (carbs > 0) { if (carbs > 0) {
carbsFromJson(json)?.let { carb -> carbsFromJson(json)?.let { carb ->
repository.runTransactionForResult(SyncNsCarbsTransaction(carb)) repository.runTransactionForResult(SyncNsCarbsTransaction(carb, invalidateByNsOnly = false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -143,7 +143,7 @@ class NSClientAddUpdateWorker(
insulin > 0 || carbs > 0 -> Any() insulin > 0 || carbs > 0 -> Any()
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text -> eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
temporaryTargetFromJson(json)?.let { temporaryTarget -> temporaryTargetFromJson(json)?.let { temporaryTarget ->
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget)) repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget, invalidateByNsOnly = false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it) aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -193,7 +193,7 @@ class NSClientAddUpdateWorker(
eventType == TherapyEvent.Type.APS_OFFLINE.text || eventType == TherapyEvent.Type.APS_OFFLINE.text ||
eventType == TherapyEvent.Type.PUMP_BATTERY_CHANGE.text -> eventType == TherapyEvent.Type.PUMP_BATTERY_CHANGE.text ->
therapyEventFromJson(json)?.let { therapyEvent -> therapyEventFromJson(json)?.let { therapyEvent ->
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent)) repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent, invalidateByNsOnly = false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -228,7 +228,7 @@ class NSClientAddUpdateWorker(
} ?: aapsLogger.error("Error parsing TherapyEvent json $json") } ?: aapsLogger.error("Error parsing TherapyEvent json $json")
eventType == TherapyEvent.Type.COMBO_BOLUS.text -> eventType == TherapyEvent.Type.COMBO_BOLUS.text ->
extendedBolusFromJson(json)?.let { extendedBolus -> extendedBolusFromJson(json)?.let { extendedBolus ->
repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus)) repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus, invalidateByNsOnly = false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it) aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -269,7 +269,7 @@ class NSClientAddUpdateWorker(
} ?: aapsLogger.error("Error parsing ExtendedBolus json $json") } ?: aapsLogger.error("Error parsing ExtendedBolus json $json")
eventType == TherapyEvent.Type.TEMPORARY_BASAL.text -> eventType == TherapyEvent.Type.TEMPORARY_BASAL.text ->
temporaryBasalFromJson(json)?.let { temporaryBasal -> temporaryBasalFromJson(json)?.let { temporaryBasal ->
repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal)) repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal, invalidateByNsOnly = false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it) aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))

View file

@ -41,7 +41,7 @@ class NSClientMbgWorker(
for (i in 0 until mbgArray.length()) { for (i in 0 until mbgArray.length()) {
val nsMbg = NSMbg(mbgArray.getJSONObject(i)) val nsMbg = NSMbg(mbgArray.getJSONObject(i))
if (!nsMbg.isValid()) continue if (!nsMbg.isValid()) continue
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEventFromNsMbg(nsMbg))) repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEventFromNsMbg(nsMbg), false))
.doOnError { .doOnError {
aapsLogger.error("Error while saving therapy event", it) aapsLogger.error("Error while saving therapy event", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))

View file

@ -58,7 +58,7 @@ class NSClientRemoveWorker(
// room Temporary target // room Temporary target
val temporaryTarget = temporaryTargetFromNsIdForInvalidating(nsId) val temporaryTarget = temporaryTargetFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget)) repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget, invalidateByNsOnly = true))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -78,7 +78,7 @@ class NSClientRemoveWorker(
// room Therapy Event // room Therapy Event
val therapyEvent = therapyEventFromNsIdForInvalidating(nsId) val therapyEvent = therapyEventFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent)) repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent, invalidateByNsOnly = true))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -95,7 +95,7 @@ class NSClientRemoveWorker(
// room Bolus // room Bolus
val bolus = bolusFromNsIdForInvalidating(nsId) val bolus = bolusFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsBolusTransaction(bolus)) repository.runTransactionForResult(SyncNsBolusTransaction(bolus, invalidateByNsOnly = true))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -111,7 +111,7 @@ class NSClientRemoveWorker(
// room Carbs // room Carbs
val carbs = carbsFromNsIdForInvalidating(nsId) val carbs = carbsFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsCarbsTransaction(carbs)) repository.runTransactionForResult(SyncNsCarbsTransaction(carbs, invalidateByNsOnly = true))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -127,7 +127,7 @@ class NSClientRemoveWorker(
// room TemporaryBasal // room TemporaryBasal
val temporaryBasal = temporaryBasalFromNsIdForInvalidating(nsId) val temporaryBasal = temporaryBasalFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal)) repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal, invalidateByNsOnly = true))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))
@ -143,7 +143,7 @@ class NSClientRemoveWorker(
} }
// room ExtendedBolus // room ExtendedBolus
val extendedBolus = extendedBolusFromNsIdForInvalidating(nsId) val extendedBolus = extendedBolusFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus)) repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus, invalidateByNsOnly = true))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it)
ret = Result.failure(workDataOf("Error" to it)) ret = Result.failure(workDataOf("Error" to it))

View file

@ -16,12 +16,14 @@ import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TemporaryBasal import info.nightscout.androidaps.database.entities.TemporaryBasal
import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.database.interfaces.end
import info.nightscout.androidaps.events.* import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.iobCalc
import info.nightscout.androidaps.extensions.toTemporaryBasal
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
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.plugins.iob.iobCobCalculator.data.AutosensData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryBgData
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
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
@ -30,15 +32,12 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.iobCalc
import info.nightscout.androidaps.extensions.toTemporaryBasal
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 io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import org.json.JSONArray import org.json.JSONArray
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import kotlin.math.abs import kotlin.math.abs
@ -73,8 +72,9 @@ open class IobCobCalculatorPlugin @Inject constructor(
), IobCobCalculator { ), IobCobCalculator {
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
private var iobTable = LongSparseArray<IobTotal?>() // oldest at index 0
private var absIobTable = LongSparseArray<IobTotal?>() // oldest at index 0, absolute insulin in the body private var iobTable = LongSparseArray<IobTotal>() // oldest at index 0
private var absIobTable = LongSparseArray<IobTotal>() // oldest at index 0, absolute insulin in the body
private var autosensDataTable = LongSparseArray<AutosensData>() // oldest at index 0 private var autosensDataTable = LongSparseArray<AutosensData>() // oldest at index 0
private var basalDataTable = LongSparseArray<BasalData>() // oldest at index 0 private var basalDataTable = LongSparseArray<BasalData>() // oldest at index 0
@Volatile override var bgReadings: List<GlucoseValue> = listOf() // newest at index 0 @Volatile override var bgReadings: List<GlucoseValue> = listOf() // newest at index 0
@ -91,43 +91,17 @@ open class IobCobCalculatorPlugin @Inject constructor(
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
// EventConfigBuilderChange // EventConfigBuilderChange
disposable.add(rxBus disposable += rxBus
.toObservable(EventConfigBuilderChange::class.java) .toObservable(EventConfigBuilderChange::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe({ event -> .subscribe({ event -> resetData("onEventConfigBuilderChange", event) }, fabricPrivacy::logException)
stopCalculation("onEventConfigBuilderChange")
synchronized(dataLock) {
aapsLogger.debug(LTag.AUTOSENS, "Invalidating cached data because of configuration change.")
resetData()
}
runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event)
}, fabricPrivacy::logException)
)
// EventNewBasalProfile // EventNewBasalProfile
disposable.add(rxBus disposable += rxBus
.toObservable(EventNewBasalProfile::class.java) .toObservable(EventNewBasalProfile::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe({ event -> .subscribe({ event -> resetData("onNewProfile", event) }, fabricPrivacy::logException)
stopCalculation("onNewProfile")
synchronized(dataLock) {
aapsLogger.debug(LTag.AUTOSENS, "Invalidating cached data because of new profile.")
resetData()
}
runCalculation("onNewProfile", System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event)
}, fabricPrivacy::logException)
)
// EventNewBG .... cannot be used for invalidating because only event with last BG is fired
disposable.add(rxBus
.toObservable(EventNewBG::class.java)
.observeOn(aapsSchedulers.io)
.debounce(1L, TimeUnit.SECONDS)
.subscribe({ event ->
stopCalculation("onEventNewBG")
runCalculation("onEventNewBG", System.currentTimeMillis(), bgDataReload = true, limitDataToOldestAvailable = true, cause = event)
}, fabricPrivacy::logException)
)
// EventPreferenceChange // EventPreferenceChange
disposable.add(rxBus disposable += rxBus
.toObservable(EventPreferenceChange::class.java) .toObservable(EventPreferenceChange::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe({ event -> .subscribe({ event ->
@ -139,33 +113,19 @@ open class IobCobCalculatorPlugin @Inject constructor(
event.isChanged(resourceHelper, R.string.key_openapsama_autosens_max) || event.isChanged(resourceHelper, R.string.key_openapsama_autosens_max) ||
event.isChanged(resourceHelper, R.string.key_openapsama_autosens_min) || event.isChanged(resourceHelper, R.string.key_openapsama_autosens_min) ||
event.isChanged(resourceHelper, R.string.key_insulin_oref_peak)) { event.isChanged(resourceHelper, R.string.key_insulin_oref_peak)) {
stopCalculation("onEventPreferenceChange") resetData("onEventPreferenceChange", event)
synchronized(dataLock) {
aapsLogger.debug(LTag.AUTOSENS, "Invalidating cached data because of preference change.")
resetData()
}
runCalculation("onEventPreferenceChange", System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event)
} }
}, fabricPrivacy::logException) }, fabricPrivacy::logException)
)
// EventAppInitialized // EventAppInitialized
disposable.add(rxBus disposable += rxBus
.toObservable(EventAppInitialized::class.java) .toObservable(EventAppInitialized::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe({ event -> runCalculation("onEventAppInitialized", System.currentTimeMillis(), bgDataReload = true, limitDataToOldestAvailable = true, cause = event) }, fabricPrivacy::logException) .subscribe({ event -> runCalculation("onEventAppInitialized", System.currentTimeMillis(), bgDataReload = true, limitDataToOldestAvailable = true, cause = event) }, fabricPrivacy::logException)
)
// EventNewHistoryData // EventNewHistoryData
disposable.add(rxBus disposable += rxBus
.toObservable(EventNewHistoryData::class.java) .toObservable(EventNewHistoryData::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe({ event -> newHistoryData(event, false) }, fabricPrivacy::logException) .subscribe({ event -> newHistoryData(event.oldDataTimestamp, event.reloadBgData, if (event.newestGlucoseValue != null) EventNewBG(event.newestGlucoseValue) else event) }, fabricPrivacy::logException)
)
// EventNewHistoryBgData
disposable.add(rxBus
.toObservable(EventNewHistoryBgData::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ event -> newHistoryData(EventNewHistoryData(event.timestamp), true) }, fabricPrivacy::logException)
)
} }
override fun onStop() { override fun onStop() {
@ -230,7 +190,10 @@ open class IobCobCalculatorPlugin @Inject constructor(
} }
} }
private fun resetData() { private fun resetData(reason: String, event: Event?) {
stopCalculation(reason)
synchronized(dataLock) {
aapsLogger.debug(LTag.AUTOSENS, "Invalidating cached data because of $reason.")
synchronized(dataLock) { synchronized(dataLock) {
iobTable = LongSparseArray() iobTable = LongSparseArray()
autosensDataTable = LongSparseArray() autosensDataTable = LongSparseArray()
@ -238,13 +201,15 @@ open class IobCobCalculatorPlugin @Inject constructor(
absIobTable = LongSparseArray() absIobTable = LongSparseArray()
} }
} }
runCalculation(reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event)
}
fun createBucketedData() { fun createBucketedData() {
val fiveMinData = isAbout5minData val fiveMinData = isAbout5minData
if (lastUsed5minCalculation != null && lastUsed5minCalculation != fiveMinData) { if (lastUsed5minCalculation != null && lastUsed5minCalculation != fiveMinData) {
// changing mode => clear cache // changing mode => clear cache
aapsLogger.debug("Invalidating cached data because of changed mode.") aapsLogger.debug("Invalidating cached data because of changed mode.")
resetData() resetData("changed mode", null)
} }
lastUsed5minCalculation = fiveMinData lastUsed5minCalculation = fiveMinData
if (isAbout5minData) createBucketedData5min() else createBucketedDataRecalculated() if (isAbout5minData) createBucketedData5min() else createBucketedDataRecalculated()
@ -696,22 +661,25 @@ open class IobCobCalculatorPlugin @Inject constructor(
} }
} }
fun runCalculation(from: String, end: Long, bgDataReload: Boolean, limitDataToOldestAvailable: Boolean, cause: Event) { fun runCalculation(from: String, end: Long, bgDataReload: Boolean, limitDataToOldestAvailable: Boolean, cause: Event?) {
aapsLogger.debug(LTag.AUTOSENS, "Starting calculation thread: " + from + " to " + dateUtil.dateAndTimeAndSecondsString(end)) aapsLogger.debug(LTag.AUTOSENS, "Starting calculation thread: " + from + " to " + dateUtil.dateAndTimeAndSecondsString(end))
if (thread == null || thread?.state == Thread.State.TERMINATED) { if (thread == null || thread?.state == Thread.State.TERMINATED) {
thread = if (sensitivityOref1Plugin.isEnabled()) IobCobOref1Thread(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause) else IobCobThread(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause) thread =
if (sensitivityOref1Plugin.isEnabled()) IobCobOref1Thread(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause)
else IobCobThread(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause)
thread?.start() thread?.start()
} }
} }
// When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated // When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated
private fun newHistoryData(ev: EventNewHistoryData, bgDataReload: Boolean) { private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) {
//log.debug("Locking onNewHistoryData"); //log.debug("Locking onNewHistoryData");
aapsLogger.debug("XXXXXXXXXXXXX onEventNewHistoryData $oldDataTimestamp")
stopCalculation("onEventNewHistoryData") stopCalculation("onEventNewHistoryData")
synchronized(dataLock) { synchronized(dataLock) {
// clear up 5 min back for proper COB calculation // clear up 5 min back for proper COB calculation
val time = ev.time - 5 * 60 * 1000L val time = oldDataTimestamp - 5 * 60 * 1000L
aapsLogger.debug(LTag.AUTOSENS, "Invalidating cached data to: " + dateUtil.dateAndTimeAndSecondsString(time)) aapsLogger.debug(LTag.AUTOSENS, "Invalidating cached data to: " + dateUtil.dateAndTimeAndSecondsString(time))
for (index in iobTable.size() - 1 downTo 0) { for (index in iobTable.size() - 1 downTo 0) {
if (iobTable.keyAt(index) > time) { if (iobTable.keyAt(index) > time) {
@ -746,7 +714,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
} }
} }
} }
runCalculation("onEventNewHistoryData", System.currentTimeMillis(), bgDataReload, true, ev) runCalculation("onEventNewHistoryData", System.currentTimeMillis(), bgDataReload, true, event)
//log.debug("Releasing onNewHistoryData"); //log.debug("Releasing onNewHistoryData");
} }
@ -921,7 +889,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
val profile = profileFunction.getProfile(t.timestamp) ?: continue val profile = profileFunction.getProfile(t.timestamp) ?: continue
if (t.end > now) t.end = now if (t.end > now) t.end = now
val calc = t.iobCalc(toTime, profile, activePlugin.activeInsulin) val calc = t.iobCalc(toTime, profile, activePlugin.activeInsulin)
//log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob); //log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basalIob);
total.plus(calc) total.plus(calc)
} }
if (pumpInterface.isFakingTempsByExtendedBoluses) { if (pumpInterface.isFakingTempsByExtendedBoluses) {
@ -956,7 +924,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
val profile = profileFunction.getProfile(t.timestamp) ?: continue val profile = profileFunction.getProfile(t.timestamp) ?: continue
if (t.end > now) t.end = now if (t.end > now) t.end = now
val calc = t.iobCalc(toTime, profile, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget, activePlugin.activeInsulin) val calc = t.iobCalc(toTime, profile, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget, activePlugin.activeInsulin)
//log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob); //log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basalIob);
total.plus(calc) total.plus(calc)
} }
if (pumpInterface.isFakingTempsByExtendedBoluses) { if (pumpInterface.isFakingTempsByExtendedBoluses) {

View file

@ -18,7 +18,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
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
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensBgLoaded
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
@ -41,7 +40,7 @@ class IobCobOref1Thread internal constructor(
private val end: Long, private val end: Long,
private val bgDataReload: Boolean, private val bgDataReload: Boolean,
private val limitDataToOldestAvailable: Boolean, private val limitDataToOldestAvailable: Boolean,
private val cause: Event private val cause: Event?
) : Thread() { ) : Thread() {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@ -77,10 +76,10 @@ class IobCobOref1Thread internal constructor(
//log.debug("Locking calculateSensitivityData"); //log.debug("Locking calculateSensitivityData");
val oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable) val oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable)
synchronized(iobCobCalculatorPlugin.dataLock) { synchronized(iobCobCalculatorPlugin.dataLock) {
aapsLogger.debug("XXXXXXXXXXXXX START $from")
if (bgDataReload) { if (bgDataReload) {
iobCobCalculatorPlugin.loadBgData(end) iobCobCalculatorPlugin.loadBgData(end)
iobCobCalculatorPlugin.createBucketedData() iobCobCalculatorPlugin.createBucketedData()
rxBus.send(EventAutosensBgLoaded(cause))
} }
val bucketedData = iobCobCalculatorPlugin.bucketedData val bucketedData = iobCobCalculatorPlugin.bucketedData
val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable() val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable()
@ -98,6 +97,7 @@ class IobCobOref1Thread internal constructor(
if (iobCobCalculatorPlugin.stopCalculationTrigger) { if (iobCobCalculatorPlugin.stopCalculationTrigger) {
iobCobCalculatorPlugin.stopCalculationTrigger = false iobCobCalculatorPlugin.stopCalculationTrigger = false
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from") aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from")
aapsLogger.debug("XXXXXXXXXXXXX STOP")
return return
} }
// check if data already exists // check if data already exists
@ -114,6 +114,7 @@ class IobCobOref1Thread internal constructor(
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (no profile): $from") aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (no profile): $from")
return // profile not set yet return // profile not set yet
} }
aapsLogger.debug("XXXXXXXXXXXXX FOR $bgTime ${dateUtil.dateAndTimeString(bgTime)}")
aapsLogger.debug(LTag.AUTOSENS, "Processing calculation thread: " + from + " (" + i + "/" + bucketedData.size + ")") aapsLogger.debug(LTag.AUTOSENS, "Processing calculation thread: " + from + " (" + i + "/" + bucketedData.size + ")")
val sens = profile.getIsfMgdl(bgTime) val sens = profile.getIsfMgdl(bgTime)
val autosensData = AutosensData(injector) val autosensData = AutosensData(injector)
@ -190,6 +191,7 @@ class IobCobOref1Thread internal constructor(
} }
val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet() val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
for (recentCarbTreatment in recentCarbTreatments) { for (recentCarbTreatment in recentCarbTreatments) {
aapsLogger.debug("XXXXXXXXXXXXX $bgTime ${dateUtil.dateAndTimeString(bgTime)} $recentCarbTreatment")
autosensData.carbsFromBolus += recentCarbTreatment.amount autosensData.carbsFromBolus += recentCarbTreatment.amount
val isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled() val isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()
autosensData.activeCarbsList.add(autosensData.CarbsInPast(recentCarbTreatment, isAAPSOrWeighted)) autosensData.activeCarbsList.add(autosensData.CarbsInPast(recentCarbTreatment, isAAPSOrWeighted))

View file

@ -18,7 +18,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
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
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensBgLoaded
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
@ -40,7 +39,7 @@ class IobCobThread @Inject internal constructor(
private val end: Long, private val end: Long,
private val bgDataReload: Boolean, private val bgDataReload: Boolean,
private val limitDataToOldestAvailable: Boolean, private val limitDataToOldestAvailable: Boolean,
private val cause: Event private val cause: Event?
) : Thread() { ) : Thread() {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@ -79,7 +78,6 @@ class IobCobThread @Inject internal constructor(
if (bgDataReload) { if (bgDataReload) {
iobCobCalculatorPlugin.loadBgData(end) iobCobCalculatorPlugin.loadBgData(end)
iobCobCalculatorPlugin.createBucketedData() iobCobCalculatorPlugin.createBucketedData()
rxBus.send(EventAutosensBgLoaded(cause))
} }
val bucketedData = iobCobCalculatorPlugin.bucketedData val bucketedData = iobCobCalculatorPlugin.bucketedData
val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable() val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable()

View file

@ -1,6 +0,0 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.events.EventLoop
class EventAutosensBgLoaded(var cause: Event) : EventLoop()

View file

@ -1,5 +0,0 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
import info.nightscout.androidaps.events.Event
class EventNewHistoryBgData(val timestamp: Long) : Event()

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.events.Event
class EventNewHistoryData(var time: Long) : Event() class EventNewHistoryData(val oldDataTimestamp: Long, val reloadBgData: Boolean, val newestGlucoseValue : GlucoseValue? = null) : Event()

View file

@ -19,23 +19,17 @@ import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import dagger.android.HasAndroidInjector; import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.ICallback;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface; import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.interfaces.TreatmentServiceInterface; import info.nightscout.androidaps.interfaces.TreatmentServiceInterface;
import info.nightscout.androidaps.interfaces.UpdateReturn; import info.nightscout.androidaps.interfaces.UpdateReturn;
@ -43,9 +37,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.openhumans.OpenHumansUploader; import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.rx.AapsSchedulers; import info.nightscout.androidaps.utils.rx.AapsSchedulers;
@ -64,9 +56,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
@Inject OpenHumansUploader openHumansUploader; @Inject OpenHumansUploader openHumansUploader;
@Inject AapsSchedulers aapsSchedulers; @Inject AapsSchedulers aapsSchedulers;
private static final ScheduledExecutorService treatmentEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledTreatmentEventPost = null;
public TreatmentService(HasAndroidInjector injector) { public TreatmentService(HasAndroidInjector injector) {
injector.androidInjector().inject(this); injector.androidInjector().inject(this);
onCreate(); onCreate();
@ -193,72 +182,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
} }
} }
/**
* A place to centrally register events to be posted, if any data changed.
* This should be implemented in an abstract service-class.
* <p>
* We do need to make sure, that ICallback is extended to be able to handle multiple
* events, or handle a list of events.
* <p>
* on some methods the earliestDataChange event is handled separatly, in that it is checked if it is
* set to null by another event already (eg. scheduleExtendedBolusChange).
*
* @param event
* @param eventWorker
* @param callback
*/
private void scheduleEvent(final Event event, ScheduledExecutorService eventWorker,
final ICallback callback) {
class PostRunnable implements Runnable {
public void run() {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventReloadTreatmentData");
rxBus.send(event);
if (DatabaseHelper.earliestDataChange != null) {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventNewHistoryData");
rxBus.send(new EventNewHistoryData(DatabaseHelper.earliestDataChange));
}
DatabaseHelper.earliestDataChange = null;
callback.setPost(null);
}
}
// prepare task for execution in 1 sec
// cancel waiting task to prevent sending multiple posts
ScheduledFuture<?> scheduledFuture = callback.getPost();
if (scheduledFuture != null)
scheduledFuture.cancel(false);
Runnable task = new PostRunnable();
final int sec = 1;
callback.setPost(eventWorker.schedule(task, sec, TimeUnit.SECONDS));
}
/**
* Schedule a foodChange Event.
*/
public void scheduleTreatmentChange(@Nullable final Treatment treatment, boolean runImmediately) {
if (runImmediately) {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventReloadTreatmentData");
rxBus.send(new EventReloadTreatmentData(new EventTreatmentChange()));
if (DatabaseHelper.earliestDataChange != null) {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventNewHistoryData");
rxBus.send(new EventNewHistoryData(DatabaseHelper.earliestDataChange));
}
DatabaseHelper.earliestDataChange = null;
} else {
this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange()), treatmentEventWorker, new ICallback() {
@Override
public void setPost(ScheduledFuture<?> post) {
scheduledTreatmentEventPost = post;
}
@Override
public ScheduledFuture<?> getPost() {
return scheduledTreatmentEventPost;
}
});
}
}
public long count() { public long count() {
try { try {
return this.getDao().countOf(); return this.getDao().countOf();
@ -284,6 +207,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
*/ */
// return true if new record is created // return true if new record is created
public UpdateReturn createOrUpdate(Treatment treatment) { public UpdateReturn createOrUpdate(Treatment treatment) {
/*
if (treatment != null && treatment.source == Source.NONE) { if (treatment != null && treatment.source == Source.NONE) {
aapsLogger.error("Coder error: source is not set for treatment: " + treatment, new Exception()); aapsLogger.error("Coder error: source is not set for treatment: " + treatment, new Exception());
//FabricPrivacy.logException(new Exception("Coder error: source is not set for treatment: " + treatment)); //FabricPrivacy.logException(new Exception("Coder error: source is not set for treatment: " + treatment));
@ -406,12 +330,13 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
} catch (SQLException e) { } catch (SQLException e) {
aapsLogger.error("Unhandled exception", e); aapsLogger.error("Unhandled exception", e);
} }
*/
return new UpdateReturn(false, false); return new UpdateReturn(false, false);
} }
@NotNull public UpdateReturn createOrUpdateMedtronic(@NotNull Treatment treatment, boolean fromNightScout) { @NotNull public UpdateReturn createOrUpdateMedtronic(@NotNull Treatment treatment, boolean fromNightScout) {
/*
if (MedtronicHistoryData.doubleBolusDebug) if (MedtronicHistoryData.doubleBolusDebug)
aapsLogger.debug(LTag.DATATREATMENTS, "DoubleBolusDebug: createOrUpdateMedtronic:: originalTreatment={}, fromNightScout={}", treatment, fromNightScout); aapsLogger.debug(LTag.DATATREATMENTS, "DoubleBolusDebug: createOrUpdateMedtronic:: originalTreatment={}, fromNightScout={}", treatment, fromNightScout);
@ -460,6 +385,8 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
} catch (SQLException e) { } catch (SQLException e) {
aapsLogger.error("Unhandled SQL exception: {}", e.getMessage(), e); aapsLogger.error("Unhandled SQL exception: {}", e.getMessage(), e);
} }
*/
return new UpdateReturn(false, false); return new UpdateReturn(false, false);
} }

View file

@ -39,6 +39,7 @@ 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.extensions.iobCalc import info.nightscout.androidaps.extensions.iobCalc
import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
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
@ -102,7 +103,9 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribeBy( .subscribeBy(
onError = { aapsLogger.error("Error removing entries", it) }, onError = { aapsLogger.error("Error removing entries", it) },
onComplete = { rxBus.send(EventTreatmentChange()) } onComplete = {
rxBus.send(EventTreatmentChange())
rxBus.send(EventNewHistoryData(0, false)) }
) )
rxBus.send(EventNSClientRestart()) rxBus.send(EventNSClientRestart())
} }

View file

@ -3,4 +3,4 @@ package info.nightscout.androidaps.events
import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.events.EventLoop import info.nightscout.androidaps.events.EventLoop
class EventAutosensCalculationFinished(var cause: Event) : EventLoop() class EventAutosensCalculationFinished(val cause: Event?) : EventLoop()

View file

@ -5,7 +5,7 @@ import info.nightscout.androidaps.database.entities.Carbs
class InvalidateCarbsTransaction(val id: Long) : Transaction<InvalidateCarbsTransaction.TransactionResult>() { class InvalidateCarbsTransaction(val id: Long) : Transaction<InvalidateCarbsTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = InvalidateCarbsTransaction.TransactionResult() val result = TransactionResult()
val carbs = database.carbsDao.findById(id) val carbs = database.carbsDao.findById(id)
?: throw IllegalArgumentException("There is no such Carbs with the specified ID.") ?: throw IllegalArgumentException("There is no such Carbs with the specified ID.")
carbs.isValid = false carbs.isValid = false

View file

@ -5,7 +5,7 @@ import info.nightscout.androidaps.database.entities.Bolus
/** /**
* Sync the Bolus from NS * Sync the Bolus from NS
*/ */
class SyncNsBolusTransaction(private val bolus: Bolus) : Transaction<SyncNsBolusTransaction.TransactionResult>() { class SyncNsBolusTransaction(private val bolus: Bolus, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsBolusTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = TransactionResult() val result = TransactionResult()
@ -25,6 +25,8 @@ class SyncNsBolusTransaction(private val bolus: Bolus) : Transaction<SyncNsBolus
return result return result
} }
if (invalidateByNsOnly) return result
// not known nsId // not known nsId
val existing = database.bolusDao.findByTimestamp(bolus.timestamp) val existing = database.bolusDao.findByTimestamp(bolus.timestamp)
if (existing != null && existing.interfaceIDs.nightscoutId == null) { if (existing != null && existing.interfaceIDs.nightscoutId == null) {

View file

@ -5,7 +5,7 @@ import info.nightscout.androidaps.database.entities.Carbs
/** /**
* Sync the carbs from NS * Sync the carbs from NS
*/ */
class SyncNsCarbsTransaction(private val carbs: Carbs) : Transaction<SyncNsCarbsTransaction.TransactionResult>() { class SyncNsCarbsTransaction(private val carbs: Carbs, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsCarbsTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = TransactionResult() val result = TransactionResult()
@ -25,6 +25,8 @@ class SyncNsCarbsTransaction(private val carbs: Carbs) : Transaction<SyncNsCarbs
return result return result
} }
if (invalidateByNsOnly) return result
// not known nsId // not known nsId
val existing = database.carbsDao.findByTimestamp(carbs.timestamp) val existing = database.carbsDao.findByTimestamp(carbs.timestamp)
if (existing != null && existing.interfaceIDs.nightscoutId == null) { if (existing != null && existing.interfaceIDs.nightscoutId == null) {

View file

@ -7,7 +7,7 @@ import kotlin.math.abs
/** /**
* Sync the Extended bolus from NS * Sync the Extended bolus from NS
*/ */
class SyncNsExtendedBolusTransaction(private val extendedBolus: ExtendedBolus) : Transaction<SyncNsExtendedBolusTransaction.TransactionResult>() { class SyncNsExtendedBolusTransaction(private val extendedBolus: ExtendedBolus, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsExtendedBolusTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = TransactionResult() val result = TransactionResult()
@ -29,6 +29,8 @@ class SyncNsExtendedBolusTransaction(private val extendedBolus: ExtendedBolus) :
return result return result
} }
if (invalidateByNsOnly) return result
// not known nsId // not known nsId
val running = database.extendedBolusDao.getExtendedBolusActiveAt(extendedBolus.timestamp).blockingGet() val running = database.extendedBolusDao.getExtendedBolusActiveAt(extendedBolus.timestamp).blockingGet()
if (running != null && abs(running.timestamp - extendedBolus.timestamp) < 1000 && running.interfaceIDs.nightscoutId == null) { // allow missing milliseconds if (running != null && abs(running.timestamp - extendedBolus.timestamp) < 1000 && running.interfaceIDs.nightscoutId == null) { // allow missing milliseconds

View file

@ -5,7 +5,7 @@ import info.nightscout.androidaps.database.entities.Food
/** /**
* Sync the TherapyEvents from NS * Sync the TherapyEvents from NS
*/ */
class SyncNsFoodTransaction(private val food: Food) : Transaction<SyncNsFoodTransaction.TransactionResult>() { class SyncNsFoodTransaction(private val food: Food, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsFoodTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = TransactionResult() val result = TransactionResult()
@ -26,6 +26,8 @@ class SyncNsFoodTransaction(private val food: Food) : Transaction<SyncNsFoodTran
return result return result
} }
if (invalidateByNsOnly) return result
// not known nsId, add // not known nsId, add
database.foodDao.insertNewEntry(food) database.foodDao.insertNewEntry(food)
result.inserted.add(food) result.inserted.add(food)

View file

@ -7,7 +7,7 @@ import kotlin.math.abs
/** /**
* Sync the Temporary Basal from NS * Sync the Temporary Basal from NS
*/ */
class SyncNsTemporaryBasalTransaction(private val temporaryBasal: TemporaryBasal) : Transaction<SyncNsTemporaryBasalTransaction.TransactionResult>() { class SyncNsTemporaryBasalTransaction(private val temporaryBasal: TemporaryBasal, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsTemporaryBasalTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = TransactionResult() val result = TransactionResult()
@ -29,6 +29,8 @@ class SyncNsTemporaryBasalTransaction(private val temporaryBasal: TemporaryBasal
return result return result
} }
if (invalidateByNsOnly) return result
// not known nsId // not known nsId
val running = database.temporaryBasalDao.getTemporaryBasalActiveAt(temporaryBasal.timestamp).blockingGet() val running = database.temporaryBasalDao.getTemporaryBasalActiveAt(temporaryBasal.timestamp).blockingGet()
if (running != null && abs(running.timestamp - temporaryBasal.timestamp) < 1000 && running.interfaceIDs.nightscoutId == null) { // allow missing milliseconds if (running != null && abs(running.timestamp - temporaryBasal.timestamp) < 1000 && running.interfaceIDs.nightscoutId == null) { // allow missing milliseconds

View file

@ -7,7 +7,7 @@ import kotlin.math.abs
/** /**
* Sync the TemporaryTarget from NS * Sync the TemporaryTarget from NS
*/ */
class SyncNsTemporaryTargetTransaction(private val temporaryTarget: TemporaryTarget) : Transaction<SyncNsTemporaryTargetTransaction.TransactionResult>() { class SyncNsTemporaryTargetTransaction(private val temporaryTarget: TemporaryTarget, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsTemporaryTargetTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = TransactionResult() val result = TransactionResult()
@ -29,6 +29,8 @@ class SyncNsTemporaryTargetTransaction(private val temporaryTarget: TemporaryTar
return result return result
} }
if (invalidateByNsOnly) return result
// not known nsId // not known nsId
val running = database.temporaryTargetDao.getTemporaryTargetActiveAt(temporaryTarget.timestamp).blockingGet() val running = database.temporaryTargetDao.getTemporaryTargetActiveAt(temporaryTarget.timestamp).blockingGet()
if (running != null && abs(running.timestamp - temporaryTarget.timestamp) < 1000 && running.interfaceIDs.nightscoutId == null) { // allow missing milliseconds if (running != null && abs(running.timestamp - temporaryTarget.timestamp) < 1000 && running.interfaceIDs.nightscoutId == null) { // allow missing milliseconds

View file

@ -5,7 +5,7 @@ import info.nightscout.androidaps.database.entities.TherapyEvent
/** /**
* Sync the TherapyEvents from NS * Sync the TherapyEvents from NS
*/ */
class SyncNsTherapyEventTransaction(private val therapyEvent: TherapyEvent) : Transaction<SyncNsTherapyEventTransaction.TransactionResult>() { class SyncNsTherapyEventTransaction(private val therapyEvent: TherapyEvent, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsTherapyEventTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
val result = TransactionResult() val result = TransactionResult()
@ -25,6 +25,8 @@ class SyncNsTherapyEventTransaction(private val therapyEvent: TherapyEvent) : Tr
return result return result
} }
if (invalidateByNsOnly) return result
// not known nsId // not known nsId
val existing = database.therapyEventDao.findByTimestamp(therapyEvent.type, therapyEvent.timestamp) val existing = database.therapyEventDao.findByTimestamp(therapyEvent.type, therapyEvent.timestamp)
if (existing != null && existing.interfaceIDs.nightscoutId == null) { if (existing != null && existing.interfaceIDs.nightscoutId == null) {

View file

@ -9,7 +9,7 @@ android {
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = JavaVersion.VERSION_1_8.toString()
} }
buildFeatures { buildFeatures {