diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt index e5d169527e..5ae92eca69 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt @@ -14,7 +14,9 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.sharedPreferences.SP import javax.inject.Inject +import javax.inject.Singleton +@Singleton class DataSyncSelectorImplementation @Inject constructor( private val sp: SP, private val aapsLogger: AAPSLogger, @@ -26,6 +28,42 @@ class DataSyncSelectorImplementation @Inject constructor( private val localProfilePlugin: LocalProfilePlugin ) : DataSyncSelector { + class QueueCounter ( + var bolusesRemaining: Long = 0L, + var carbsRemaining: Long = 0L, + var bcrRemaining: Long = 0L, + var ttsRemaining: Long = 0L, + var foodsRemaining: Long = 0L, + var gvsRemaining: Long = 0L, + var tesRemaining: Long = 0L, + var dssRemaining: Long = 0L, + var tbrsRemaining: Long = 0L, + var ebsRemaining: Long = 0L, + var pssRemaining: Long = 0L, + var epssRemaining: Long = 0L, + var oesRemaining: Long = 0L + ) { + + fun size(): Long = + bolusesRemaining + + carbsRemaining + + bcrRemaining + + ttsRemaining + + foodsRemaining + + gvsRemaining + + tesRemaining + + dssRemaining + + tbrsRemaining + + ebsRemaining + + pssRemaining + + epssRemaining + + oesRemaining + } + + private val queueCounter = QueueCounter() + + override fun queueSize(): Long = queueCounter.size() + override fun doUpload() { if (sp.getBoolean(R.string.key_ns_upload, true)) { processChangedBolusesCompat() @@ -80,8 +118,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastBolusId = -1L - @Volatile private var lastBolusTime = -1L + //private var lastBolusId = -1L + //private var lastBolusTime = -1L override fun processChangedBolusesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastBolusIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -90,18 +128,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_bolus_last_synced_id, 0) startId = 0 } - if (startId == lastBolusId && dateUtil.now() - lastBolusTime < 5000) return false - lastBolusId = startId - lastBolusTime = dateUtil.now() + //if (startId == lastBolusId && dateUtil.now() - lastBolusTime < 5000) return false + //lastBolusId = startId + //lastBolusTime = dateUtil.now() + queueCounter.bolusesRemaining = lastDbId - startId appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus -> - aapsLogger.info(LTag.DATABASE, "Loading Bolus data Start: $startId ID: ${bolus.first.id} HistoryID: ${bolus.second} ") + aapsLogger.info(LTag.DATABASE, "Loading Bolus data Start: $startId ID: ${bolus.first.id} HistoryID: ${bolus.second.id} ") when { + // only NsId changed, no need to upload + bolus.first.onlyNsIdAdded(bolus.second) -> { + confirmLastBolusIdIfGreater(bolus.second.id) + //lastBolusId = -1 + processChangedBolusesCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring Bolus. Only NS id changed ID: ${bolus.first.id} HistoryID: ${bolus.second.id} ") + return false + } // without nsId = create new bolus.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", bolus.first.toJson(true, dateUtil), DataSyncSelector.PairBolus(bolus.first, bolus.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", bolus.first.toJson(true, dateUtil), DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId") // with nsId = update bolus.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", bolus.first.interfaceIDs.nightscoutId, bolus.first.toJson(false, dateUtil), DataSyncSelector.PairBolus(bolus.first, bolus.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", bolus.first.interfaceIDs.nightscoutId, bolus.first.toJson(false, dateUtil), DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId") } return true } @@ -123,8 +170,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastCarbsId = -1L - @Volatile private var lastCarbsTime = -1L + //private var lastCarbsId = -1L + //private var lastCarbsTime = -1L override fun processChangedCarbsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastCarbsIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -133,18 +180,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_carbs_last_synced_id, 0) startId = 0 } - if (startId == lastCarbsId && dateUtil.now() - lastCarbsTime < 5000) return false - lastCarbsId = startId - lastCarbsTime = dateUtil.now() + //if (startId == lastCarbsId && dateUtil.now() - lastCarbsTime < 5000) return false + //lastCarbsId = startId + //lastCarbsTime = dateUtil.now() + queueCounter.carbsRemaining = lastDbId - startId appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb -> - aapsLogger.info(LTag.DATABASE, "Loading Carbs data Start: $startId ID: ${carb.first.id} HistoryID: ${carb.second} ") + aapsLogger.info(LTag.DATABASE, "Loading Carbs data Start: $startId ID: ${carb.first.id} HistoryID: ${carb.second.id} ") when { + // only NsId changed, no need to upload + carb.first.onlyNsIdAdded(carb.second) -> { + confirmLastCarbsIdIfGreater(carb.second.id) + //lastCarbsId = -1 + processChangedCarbsCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring Carbs. Only NS id changed ID: ${carb.first.id} HistoryID: ${carb.second.id} ") + return false + } // without nsId = create new carb.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", carb.first.toJson(true, dateUtil), DataSyncSelector.PairCarbs(carb.first, carb.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", carb.first.toJson(true, dateUtil), DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") // with nsId = update carb.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", carb.first.interfaceIDs.nightscoutId, carb.first.toJson(false, dateUtil), DataSyncSelector.PairCarbs(carb.first, carb.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", carb.first.interfaceIDs.nightscoutId, carb.first.toJson(false, dateUtil), DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") } return true } @@ -166,8 +222,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastBcrId = -1L - @Volatile private var lastBcrTime = -1L + //private var lastBcrId = -1L + //private var lastBcrTime = -1L override fun processChangedBolusCalculatorResultsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastBolusCalculatorResultIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -176,18 +232,28 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0) startId = 0 } - if (startId == lastBcrId && dateUtil.now() - lastBcrTime < 5000) return false - lastBcrId = startId - lastBcrTime = dateUtil.now() + //if (startId == lastBcrId && dateUtil.now() - lastBcrTime < 5000) return false + //lastBcrId = startId + //lastBcrTime = dateUtil.now() + queueCounter.bcrRemaining = lastDbId - startId appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult -> - aapsLogger.info(LTag.DATABASE, "Loading BolusCalculatorResult data Start: $startId ID: ${bolusCalculatorResult.first.id} HistoryID: ${bolusCalculatorResult.second} ") + aapsLogger.info(LTag.DATABASE, "Loading BolusCalculatorResult data Start: $startId ID: ${bolusCalculatorResult.first.id} HistoryID: ${bolusCalculatorResult.second.id} ") when { + // only NsId changed, no need to upload + bolusCalculatorResult.first.onlyNsIdAdded(bolusCalculatorResult.second) -> { + confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id) + //lastBcrId = -1 + processChangedBolusCalculatorResultsCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring BolusCalculatorResult. Only NS id changed ID: ${bolusCalculatorResult.first.id} HistoryID: ${bolusCalculatorResult.second.id} ") + return false + } // without nsId = create new bolusCalculatorResult.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", bolusCalculatorResult.first.toJson(true, dateUtil), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", bolusCalculatorResult.first.toJson(true, dateUtil), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId") // with nsId = update bolusCalculatorResult.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", bolusCalculatorResult.first.interfaceIDs.nightscoutId, bolusCalculatorResult.first.toJson(false, dateUtil), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", bolusCalculatorResult.first.interfaceIDs.nightscoutId, bolusCalculatorResult.first.toJson(false, dateUtil), + DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId") } return true } @@ -209,8 +275,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastTtId = -1L - @Volatile private var lastTtTime = -1L + //private var lastTtId = -1L + //private var lastTtTime = -1L override fun processChangedTempTargetsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastTempTargetIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -219,18 +285,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_temporary_target_last_synced_id, 0) startId = 0 } - if (startId == lastTtId && dateUtil.now() - lastTtTime < 5000) return false - lastTtId = startId - lastTtTime = dateUtil.now() + //if (startId == lastTtId && dateUtil.now() - lastTtTime < 5000) return false + //lastTtId = startId + //lastTtTime = dateUtil.now() + queueCounter.ttsRemaining = lastDbId - startId appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt -> - aapsLogger.info(LTag.DATABASE, "Loading TemporaryTarget data Start: $startId ID: ${tt.first.id} HistoryID: ${tt.second} ") + aapsLogger.info(LTag.DATABASE, "Loading TemporaryTarget data Start: $startId ID: ${tt.first.id} HistoryID: ${tt.second.id} ") when { + // only NsId changed, no need to upload + tt.first.onlyNsIdAdded(tt.second) -> { + confirmLastTempTargetsIdIfGreater(tt.second.id) + //lastTtId = -1 + processChangedTempTargetsCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring TemporaryTarget. Only NS id changed ID: ${tt.first.id} HistoryID: ${tt.second.id} ") + return false + } // without nsId = create new tt.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", tt.first.toJson(true, profileFunction.getUnits(), dateUtil), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", tt.first.toJson(true, profileFunction.getUnits(), dateUtil), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId") // existing with nsId = update tt.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", tt.first.interfaceIDs.nightscoutId, tt.first.toJson(false, profileFunction.getUnits(), dateUtil), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", tt.first.interfaceIDs.nightscoutId, tt.first.toJson(false, profileFunction.getUnits(), dateUtil), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId") } return true } @@ -252,8 +327,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastFoodId = -1L - @Volatile private var lastFoodTime = -1L + //private var lastFoodId = -1L + //private var lastFoodTime = -1L override fun processChangedFoodsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastFoodIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -262,18 +337,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_food_last_synced_id, 0) startId = 0 } - if (startId == lastFoodId && dateUtil.now() - lastFoodTime < 5000) return false - lastFoodId = startId - lastFoodTime = dateUtil.now() + //if (startId == lastFoodId && dateUtil.now() - lastFoodTime < 5000) return false + //lastFoodId = startId + //lastFoodTime = dateUtil.now() + queueCounter.foodsRemaining = lastDbId - startId appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food -> aapsLogger.info(LTag.DATABASE, "Loading Food data Start: $startId ID: ${food.first.id} HistoryID: ${food.second} ") when { + // only NsId changed, no need to upload + food.first.onlyNsIdAdded(food.second) -> { + confirmLastFoodIdIfGreater(food.second.id) + //lastFoodId = -1 + processChangedFoodsCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring Food. Only NS id changed ID: ${food.first.id} HistoryID: ${food.second.id} ") + return false + } // without nsId = create new food.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("food", food.first.toJson(true), DataSyncSelector.PairFood(food.first, food.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("food", food.first.toJson(true), DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") // with nsId = update food.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("food", food.first.interfaceIDs.nightscoutId, food.first.toJson(false), DataSyncSelector.PairFood(food.first, food.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("food", food.first.interfaceIDs.nightscoutId, food.first.toJson(false), DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") } return true } @@ -295,8 +379,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastGvId = -1L - @Volatile private var lastGvTime = -1L + //private var lastGvId = -1L + //private var lastGvTime = -1L override fun processChangedGlucoseValuesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastGlucoseValueIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -305,24 +389,33 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_glucose_value_last_synced_id, 0) startId = 0 } - if (startId == lastGvId && dateUtil.now() - lastGvTime < 5000) return false - lastGvId = startId - lastGvTime = dateUtil.now() + //if (startId == lastGvId && dateUtil.now() - lastGvTime < 5000) return false + //lastGvId = startId + //lastGvTime = dateUtil.now() + queueCounter.gvsRemaining = lastDbId - startId appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv -> - aapsLogger.info(LTag.DATABASE, "Loading GlucoseValue data Start: $startId ID: ${gv.first.id} HistoryID: ${gv.second} ") + aapsLogger.info(LTag.DATABASE, "Loading GlucoseValue data ID: ${gv.first.id} HistoryID: ${gv.second.id} ") if (activePlugin.activeBgSource.shouldUploadToNs(gv.first)) { when { + // only NsId changed, no need to upload + gv.first.onlyNsIdAdded(gv.second) -> { + confirmLastGlucoseValueIdIfGreater(gv.second.id) + //lastGvId = -1 + processChangedGlucoseValuesCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring GlucoseValue. Only NS id changed ID: ${gv.first.id} HistoryID: ${gv.second.id} ") + return false + } // without nsId = create new gv.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("entries", gv.first.toJson(true, dateUtil), DataSyncSelector.PairGlucoseValue(gv.first, gv.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("entries", gv.first.toJson(true, dateUtil), DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") // with nsId = update gv.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("entries", gv.first.interfaceIDs.nightscoutId, gv.first.toJson(false, dateUtil), DataSyncSelector.PairGlucoseValue(gv.first, gv.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("entries", gv.first.interfaceIDs.nightscoutId, gv.first.toJson(false, dateUtil), DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") } return true } else { - confirmLastGlucoseValueIdIfGreater(gv.second) - lastGvId = -1 + confirmLastGlucoseValueIdIfGreater(gv.second.id) + //lastGvId = -1 processChangedGlucoseValuesCompat() } } @@ -344,8 +437,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastTeId = -1L - @Volatile private var lastTeTime = -1L + //private var lastTeId = -1L + //private var lastTeTime = -1L override fun processChangedTherapyEventsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastTherapyEventIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -354,18 +447,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_therapy_event_last_synced_id, 0) startId = 0 } - if (startId == lastTeId && dateUtil.now() - lastTeTime < 5000) return false - lastTeId = startId - lastTeTime = dateUtil.now() + //if (startId == lastTeId && dateUtil.now() - lastTeTime < 5000) return false + //lastTeId = startId + //lastTeTime = dateUtil.now() + queueCounter.tesRemaining = lastDbId - startId appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te -> aapsLogger.info(LTag.DATABASE, "Loading TherapyEvents data Start: $startId ID: ${te.first.id} HistoryID: ${te.second} ") when { + // only NsId changed, no need to upload + te.first.onlyNsIdAdded(te.second) -> { + confirmLastTherapyEventIdIfGreater(te.second.id) + //lastTeId = -1 + processChangedTherapyEventsCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring TherapyEvents. Only NS id changed ID: ${te.first.id} HistoryID: ${te.second.id} ") + return false + } // without nsId = create new te.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", te.first.toJson(true, dateUtil), DataSyncSelector.PairTherapyEvent(te.first, te.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", te.first.toJson(true, dateUtil), DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") // nsId = update te.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", te.first.interfaceIDs.nightscoutId, te.first.toJson(false, dateUtil), DataSyncSelector.PairTherapyEvent(te.first, te.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", te.first.interfaceIDs.nightscoutId, te.first.toJson(false, dateUtil), DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") } return true } @@ -386,8 +488,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastDsId = -1L - @Volatile private var lastDsTime = -1L + //private var lastDsId = -1L + //private var lastDsTime = -1L override fun processChangedDeviceStatusesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -396,9 +498,10 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_device_status_last_synced_id, 0) startId = 0 } - if (startId == lastDsId && dateUtil.now() - lastDsTime < 5000) return false - lastDsId = startId - lastDsTime = dateUtil.now() + //if (startId == lastDsId && dateUtil.now() - lastDsTime < 5000) return false + //lastDsId = startId + //lastDsTime = dateUtil.now() + queueCounter.dssRemaining = lastDbId - startId appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus -> aapsLogger.info(LTag.DATABASE, "Loading DeviceStatus data Start: $startId ID: ${deviceStatus.id}") when { @@ -428,8 +531,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastTbrId = -1L - @Volatile private var lastTbrTime = -1L + //private var lastTbrId = -1L + //private var lastTbrTime = -1L override fun processChangedTemporaryBasalsCompat(): Boolean { val useAbsolute = sp.getBoolean(R.string.key_ns_sync_use_absolute, false) val lastDbIdWrapped = appRepository.getLastTemporaryBasalIdWrapped().blockingGet() @@ -439,25 +542,34 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, 0) startId = 0 } - if (startId == lastTbrId && dateUtil.now() - lastTbrTime < 5000) return false - lastTbrId = startId - lastTbrTime = dateUtil.now() + //if (startId == lastTbrId && dateUtil.now() - lastTbrTime < 5000) return false + //lastTbrId = startId + //lastTbrTime = dateUtil.now() + queueCounter.tbrsRemaining = lastDbId - startId appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb -> aapsLogger.info(LTag.DATABASE, "Loading TemporaryBasal data Start: $startId ID: ${tb.first.id} HistoryID: ${tb.second} ") val profile = profileFunction.getProfile(tb.first.timestamp) if (profile != null) { when { + // only NsId changed, no need to upload + tb.first.onlyNsIdAdded(tb.second) -> { + confirmLastTemporaryBasalIdIfGreater(tb.second.id) + //lastTbrId = -1 + processChangedTemporaryBasalsCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring TemporaryBasal. Only NS id changed ID: ${tb.first.id} HistoryID: ${tb.second.id} ") + return false + } // without nsId = create new tb.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", tb.first.toJson(true, profile, dateUtil, useAbsolute), DataSyncSelector.PairTemporaryBasal(tb.first, tb.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", tb.first.toJson(true, profile, dateUtil, useAbsolute), DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId") // with nsId = update tb.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", tb.first.interfaceIDs.nightscoutId, tb.first.toJson(false, profile, dateUtil, useAbsolute), DataSyncSelector.PairTemporaryBasal(tb.first, tb.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", tb.first.interfaceIDs.nightscoutId, tb.first.toJson(false, profile, dateUtil, useAbsolute), DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId") } return true } else { - confirmLastTemporaryBasalIdIfGreater(tb.second) - lastTbrId = -1 + confirmLastTemporaryBasalIdIfGreater(tb.second.id) + //lastTbrId = -1 processChangedTemporaryBasalsCompat() } } @@ -479,8 +591,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastEbId = -1L - @Volatile private var lastEbTime = -1L + //private var lastEbId = -1L + //private var lastEbTime = -1L override fun processChangedExtendedBolusesCompat(): Boolean { val useAbsolute = sp.getBoolean(R.string.key_ns_sync_use_absolute, false) val lastDbIdWrapped = appRepository.getLastExtendedBolusIdWrapped().blockingGet() @@ -490,25 +602,34 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, 0) startId = 0 } - if (startId == lastEbId && dateUtil.now() - lastEbTime < 5000) return false - lastEbId = startId - lastEbTime = dateUtil.now() + //if (startId == lastEbId && dateUtil.now() - lastEbTime < 5000) return false + //lastEbId = startId + //lastEbTime = dateUtil.now() + queueCounter.ebsRemaining = lastDbId - startId appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb -> aapsLogger.info(LTag.DATABASE, "Loading ExtendedBolus data Start: $startId ID: ${eb.first.id} HistoryID: ${eb.second} ") val profile = profileFunction.getProfile(eb.first.timestamp) if (profile != null) { when { + // only NsId changed, no need to upload + eb.first.onlyNsIdAdded(eb.second) -> { + confirmLastExtendedBolusIdIfGreater(eb.second.id) + //lastEbId = -1 + processChangedExtendedBolusesCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring ExtendedBolus. Only NS id changed ID: ${eb.first.id} HistoryID: ${eb.second.id} ") + return false + } // without nsId = create new eb.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", eb.first.toJson(true, profile, dateUtil, useAbsolute), DataSyncSelector.PairExtendedBolus(eb.first, eb.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", eb.first.toJson(true, profile, dateUtil, useAbsolute), DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId") // with nsId = update eb.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", eb.first.interfaceIDs.nightscoutId, eb.first.toJson(false, profile, dateUtil, useAbsolute), DataSyncSelector.PairExtendedBolus(eb.first, eb.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", eb.first.interfaceIDs.nightscoutId, eb.first.toJson(false, profile, dateUtil, useAbsolute), DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId") } return true } else { - confirmLastExtendedBolusIdIfGreater(eb.second) - lastEbId = -1 + confirmLastExtendedBolusIdIfGreater(eb.second.id) + //lastEbId = -1 processChangedExtendedBolusesCompat() } } @@ -529,8 +650,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastPsId = -1L - @Volatile private var lastPsTime = -1L + //private var lastPsId = -1L + //private var lastPsTime = -1L override fun processChangedProfileSwitchesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastProfileSwitchIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -539,18 +660,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_profile_switch_last_synced_id, 0) startId = 0 } - if (startId == lastPsId && dateUtil.now() - lastPsTime < 5000) return false - lastPsId = startId - lastPsTime = dateUtil.now() + //if (startId == lastPsId && dateUtil.now() - lastPsTime < 5000) return false + //lastPsId = startId + //lastPsTime = dateUtil.now() + queueCounter.pssRemaining = lastDbId - startId appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps -> aapsLogger.info(LTag.DATABASE, "Loading ProfileSwitch data Start: $startId ID: ${ps.first.id} HistoryID: ${ps.second} ") when { + // only NsId changed, no need to upload + ps.first.onlyNsIdAdded(ps.second) -> { + confirmLastProfileSwitchIdIfGreater(ps.second.id) + //lastPsId = -1 + processChangedProfileSwitchesCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring ProfileSwitch. Only NS id changed ID: ${ps.first.id} HistoryID: ${ps.second.id} ") + return false + } // without nsId = create new ps.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", ps.first.toJson(true, dateUtil), DataSyncSelector.PairProfileSwitch(ps.first, ps.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", ps.first.toJson(true, dateUtil), DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") // with nsId = update ps.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", ps.first.interfaceIDs.nightscoutId, ps.first.toJson(false, dateUtil), DataSyncSelector.PairProfileSwitch(ps.first, ps.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", ps.first.interfaceIDs.nightscoutId, ps.first.toJson(false, dateUtil), DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") } return true } @@ -571,8 +701,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastEpsId = -1L - @Volatile private var lastEpsTime = -1L + //private var lastEpsId = -1L + //private var lastEpsTime = -1L override fun processChangedEffectiveProfileSwitchesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastEffectiveProfileSwitchIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -581,18 +711,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0) startId = 0 } - if (startId == lastEpsId && dateUtil.now() - lastEpsTime < 5000) return false - lastEpsId = startId - lastEpsTime = dateUtil.now() + //if (startId == lastEpsId && dateUtil.now() - lastEpsTime < 5000) return false + //lastEpsId = startId + //lastEpsTime = dateUtil.now() + queueCounter.epssRemaining = lastDbId - startId appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps -> aapsLogger.info(LTag.DATABASE, "Loading EffectiveProfileSwitch data Start: $startId ID: ${ps.first.id} HistoryID: ${ps.second} ") when { + // only NsId changed, no need to upload + ps.first.onlyNsIdAdded(ps.second) -> { + confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id) + //lastEpsId = -1 + processChangedEffectiveProfileSwitchesCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring EffectiveProfileSwitch. Only NS id changed ID: ${ps.first.id} HistoryID: ${ps.second.id} ") + return false + } // without nsId = create new ps.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", ps.first.toJson(true, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", ps.first.toJson(true, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") // with nsId = update ps.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", ps.first.interfaceIDs.nightscoutId, ps.first.toJson(false, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", ps.first.interfaceIDs.nightscoutId, ps.first.toJson(false, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") } return true } @@ -614,8 +753,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - @Volatile private var lastOeId = -1L - @Volatile private var lastOeTime = -1L + //private var lastOeId = -1L + //private var lastOeTime = -1L override fun processChangedOfflineEventsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastOfflineEventIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -624,18 +763,27 @@ class DataSyncSelectorImplementation @Inject constructor( sp.putLong(R.string.key_ns_offline_event_last_synced_id, 0) startId = 0 } - if (startId == lastOeId && dateUtil.now() - lastOeTime < 5000) return false - lastOeId = startId - lastOeTime = dateUtil.now() + //if (startId == lastOeId && dateUtil.now() - lastOeTime < 5000) return false + //lastOeId = startId + //lastOeTime = dateUtil.now() + queueCounter.oesRemaining = lastDbId - startId appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe -> aapsLogger.info(LTag.DATABASE, "Loading OfflineEvent data Start: $startId ID: ${oe.first.id} HistoryID: ${oe.second} ") when { + // only NsId changed, no need to upload + oe.first.onlyNsIdAdded(oe.second) -> { + confirmLastOfflineEventIdIfGreater(oe.second.id) + //lastOeId = -1 + processChangedOfflineEventsCompat() + aapsLogger.info(LTag.DATABASE, "Ignoring OfflineEvent. Only NS id changed ID: ${oe.first.id} HistoryID: ${oe.second.id} ") + return false + } // without nsId = create new oe.first.interfaceIDs.nightscoutId == null -> - nsClientPlugin.nsClientService?.dbAdd("treatments", oe.first.toJson(true, dateUtil), DataSyncSelector.PairOfflineEvent(oe.first, oe.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbAdd("treatments", oe.first.toJson(true, dateUtil), DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") // existing with nsId = update oe.first.interfaceIDs.nightscoutId != null -> - nsClientPlugin.nsClientService?.dbUpdate("treatments", oe.first.interfaceIDs.nightscoutId, oe.first.toJson(false, dateUtil), DataSyncSelector.PairOfflineEvent(oe.first, oe.second), "$startId/$lastDbId") + nsClientPlugin.nsClientService?.dbUpdate("treatments", oe.first.interfaceIDs.nightscoutId, oe.first.toJson(false, dateUtil), DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") } return true } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt index 80b508766d..0a308d5e1d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientFragment.kt @@ -101,5 +101,6 @@ class NSClientFragment : DaggerFragment() { if (nsClientPlugin.autoscroll) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN) binding.url.text = nsClientPlugin.url() binding.status.text = nsClientPlugin.status + binding.queue.text = dataSyncSelector.queueSize().toString() } } \ No newline at end of file diff --git a/app/src/main/res/layout/ns_client_fragment.xml b/app/src/main/res/layout/ns_client_fragment.xml index e10791bb52..6b41c455d5 100644 --- a/app/src/main/res/layout/ns_client_fragment.xml +++ b/app/src/main/res/layout/ns_client_fragment.xml @@ -5,141 +5,159 @@ android:orientation="vertical" tools:context=".plugins.general.nsclient.NSClientFragment"> - + + + android:text="@string/nsclientinternal_url" /> - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + android:text="@string/status" + tools:ignore="RtlHardcoded" /> - + - + - + - + android:layout_marginRight="5dp" /> - + - + - + - + - + - + + + + + + - - - + android:layout_height="wrap_content" + android:text="" /> + diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/DataSyncSelector.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/DataSyncSelector.kt index 168a51c97e..968d67c04d 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/DataSyncSelector.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/DataSyncSelector.kt @@ -20,6 +20,8 @@ interface DataSyncSelector { data class PairOfflineEvent(val value: OfflineEvent, val updateRecordId: Long) data class PairProfileStore(val value: JSONObject, val timestampSync: Long) + fun queueSize(): Long + fun doUpload() fun resetToNextFullSync() diff --git a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt index 6654bd1377..f7ec1c98ab 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt @@ -95,15 +95,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementGlucoseValue(id: Long): Maybe> = + fun getNextSyncElementGlucoseValue(id: Long): Maybe> = database.glucoseValueDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.glucoseValueDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -123,15 +123,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementTemporaryTarget(id: Long): Maybe> = + fun getNextSyncElementTemporaryTarget(id: Long): Maybe> = database.temporaryTargetDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.temporaryTargetDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -185,15 +185,15 @@ import kotlin.math.roundToInt // PROFILE SWITCH - fun getNextSyncElementProfileSwitch(id: Long): Maybe> = + fun getNextSyncElementProfileSwitch(id: Long): Maybe> = database.profileSwitchDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.profileSwitchDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -250,15 +250,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementEffectiveProfileSwitch(id: Long): Maybe> = + fun getNextSyncElementEffectiveProfileSwitch(id: Long): Maybe> = database.effectiveProfileSwitchDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.effectiveProfileSwitchDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -309,15 +309,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementTherapyEvent(id: Long): Maybe> = + fun getNextSyncElementTherapyEvent(id: Long): Maybe> = database.therapyEventDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.therapyEventDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -376,15 +376,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementFood(id: Long): Maybe> = + fun getNextSyncElementFood(id: Long): Maybe> = database.foodDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.foodDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -412,15 +412,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementBolus(id: Long): Maybe> = + fun getNextSyncElementBolus(id: Long): Maybe> = database.bolusDao.getNextModifiedOrNewAfterExclude(id, Bolus.Type.PRIMING) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.bolusDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -499,15 +499,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementCarbs(id: Long): Maybe> = + fun getNextSyncElementCarbs(id: Long): Maybe> = database.carbsDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.carbsDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -590,15 +590,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementBolusCalculatorResult(id: Long): Maybe> = + fun getNextSyncElementBolusCalculatorResult(id: Long): Maybe> = database.bolusCalculatorResultDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.bolusCalculatorResultDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -658,15 +658,15 @@ import kotlin.math.roundToInt * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementTemporaryBasal(id: Long): Maybe> = + fun getNextSyncElementTemporaryBasal(id: Long): Maybe> = database.temporaryBasalDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.temporaryBasalDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -720,15 +720,15 @@ import kotlin.math.roundToInt * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementExtendedBolus(id: Long): Maybe> = + fun getNextSyncElementExtendedBolus(id: Long): Maybe> = database.extendedBolusDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.extendedBolusDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } @@ -788,15 +788,15 @@ import kotlin.math.roundToInt * * It is a Maybe as there might be no next element. * */ - fun getNextSyncElementOfflineEvent(id: Long): Maybe> = + fun getNextSyncElementOfflineEvent(id: Long): Maybe> = database.offlineEventDao.getNextModifiedOrNewAfter(id) .flatMap { nextIdElement -> val nextIdElemReferenceId = nextIdElement.referenceId if (nextIdElemReferenceId == null) { - Maybe.just(nextIdElement to nextIdElement.id) + Maybe.just(nextIdElement to nextIdElement) } else { database.offlineEventDao.getCurrentFromHistoric(nextIdElemReferenceId) - .map { it to nextIdElement.id } + .map { it to nextIdElement } } } diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/Bolus.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/Bolus.kt index d174f9b25d..5e7538bbb2 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/Bolus.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/Bolus.kt @@ -12,12 +12,14 @@ import info.nightscout.androidaps.database.interfaces.DBEntryWithTime import info.nightscout.androidaps.database.interfaces.TraceableDBEntry import java.util.* -@Entity(tableName = TABLE_BOLUSES, +@Entity( + tableName = TABLE_BOLUSES, foreignKeys = [ ForeignKey( entity = Bolus::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("id"), Index("isValid"), @@ -27,7 +29,8 @@ import java.util.* Index("pumpType"), Index("referenceId"), Index("timestamp") - ]) + ] +) data class Bolus( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -46,6 +49,20 @@ data class Bolus( var insulinConfiguration: InsulinConfiguration? = null ) : TraceableDBEntry, DBEntryWithTime { + private fun contentEqualsTo(other: Bolus): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + amount == other.amount && + type == other.type && + isBasalInsulin == other.isBasalInsulin + + fun onlyNsIdAdded(previous: Bolus): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + enum class Type { NORMAL, SMB, diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt index 8e1f0b0532..681addd996 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt @@ -1,23 +1,30 @@ package info.nightscout.androidaps.database.entities -import androidx.room.* +import androidx.room.Embedded +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.Index +import androidx.room.PrimaryKey import info.nightscout.androidaps.database.TABLE_BOLUS_CALCULATOR_RESULTS import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.interfaces.DBEntryWithTime import info.nightscout.androidaps.database.interfaces.TraceableDBEntry -import java.util.TimeZone +import java.util.* -@Entity(tableName = TABLE_BOLUS_CALCULATOR_RESULTS, +@Entity( + tableName = TABLE_BOLUS_CALCULATOR_RESULTS, foreignKeys = [ForeignKey( entity = BolusCalculatorResult::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("referenceId"), Index("timestamp"), Index("id"), Index("isValid") - ]) + ] +) data class BolusCalculatorResult( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -58,4 +65,45 @@ data class BolusCalculatorResult( var percentageCorrection: Int, var profileName: String, var note: String -) : TraceableDBEntry, DBEntryWithTime \ No newline at end of file +) : TraceableDBEntry, DBEntryWithTime { + + private fun contentEqualsTo(other: BolusCalculatorResult): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + targetBGLow == other.targetBGLow && + targetBGHigh == other.targetBGHigh && + isf == other.isf && + ic == other.ic && + bolusIOB == other.bolusIOB && + wasBolusIOBUsed == other.wasBolusIOBUsed && + basalIOB == other.basalIOB && + wasBasalIOBUsed == other.wasBasalIOBUsed && + glucoseValue == other.glucoseValue && + wasGlucoseUsed == other.wasGlucoseUsed && + glucoseDifference == other.glucoseDifference && + glucoseInsulin == other.glucoseInsulin && + glucoseTrend == other.glucoseTrend && + wasTrendUsed == other.wasTrendUsed && + trendInsulin == other.trendInsulin && + cob == other.cob && + wasCOBUsed == other.wasCOBUsed && + cobInsulin == other.cobInsulin && + carbs == other.carbs && + wereCarbsUsed == other.wereCarbsUsed && + carbsInsulin == other.carbsInsulin && + otherCorrection == other.otherCorrection && + wasSuperbolusUsed == other.wasSuperbolusUsed && + superbolusInsulin == other.superbolusInsulin && + wasTempTargetUsed == other.wasTempTargetUsed && + totalInsulin == other.totalInsulin && + percentageCorrection == other.percentageCorrection && + profileName == other.profileName && + note == other.note + + fun onlyNsIdAdded(previous: BolusCalculatorResult): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null +} \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt index c068da1bfe..9e9d703dfa 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt @@ -36,4 +36,18 @@ data class Carbs( override var utcOffset: Long = TimeZone.getDefault().getOffset(timestamp).toLong(), override var duration: Long, // in milliseconds var amount: Double -) : TraceableDBEntry, DBEntryWithTimeAndDuration \ No newline at end of file +) : TraceableDBEntry, DBEntryWithTimeAndDuration { + + private fun contentEqualsTo(other: Carbs): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + amount == other.amount && + duration == other.duration + + fun onlyNsIdAdded(previous: Carbs): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null +} \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/EffectiveProfileSwitch.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/EffectiveProfileSwitch.kt index a7ff14eb64..969a67c4f0 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/EffectiveProfileSwitch.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/EffectiveProfileSwitch.kt @@ -14,17 +14,20 @@ import info.nightscout.androidaps.database.interfaces.DBEntryWithTime import info.nightscout.androidaps.database.interfaces.TraceableDBEntry import java.util.* -@Entity(tableName = TABLE_EFFECTIVE_PROFILE_SWITCHES, +@Entity( + tableName = TABLE_EFFECTIVE_PROFILE_SWITCHES, foreignKeys = [ForeignKey( entity = EffectiveProfileSwitch::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("id"), Index("referenceId"), Index("timestamp"), Index("isValid") - ]) + ] +) data class EffectiveProfileSwitch( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -52,6 +55,28 @@ data class EffectiveProfileSwitch( var insulinConfiguration: InsulinConfiguration ) : TraceableDBEntry, DBEntryWithTime { + private fun contentEqualsTo(other: EffectiveProfileSwitch): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + basalBlocks == other.basalBlocks && + isfBlocks == other.isfBlocks && + icBlocks == other.icBlocks && + targetBlocks == other.targetBlocks && + glucoseUnit == other.glucoseUnit && + originalProfileName == other.originalProfileName && + originalCustomizedName == other.originalCustomizedName && + originalTimeshift == other.originalTimeshift && + originalPercentage == other.originalPercentage && + originalDuration == other.originalDuration && + originalEnd == other.originalEnd + + fun onlyNsIdAdded(previous: EffectiveProfileSwitch): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + enum class GlucoseUnit { MGDL, MMOL; diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/ExtendedBolus.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/ExtendedBolus.kt index c59afdd34c..f8ec3f52b4 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/ExtendedBolus.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/ExtendedBolus.kt @@ -11,11 +11,13 @@ import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration import info.nightscout.androidaps.database.interfaces.TraceableDBEntry import java.util.* -@Entity(tableName = TABLE_EXTENDED_BOLUSES, +@Entity( + tableName = TABLE_EXTENDED_BOLUSES, foreignKeys = [ForeignKey( entity = ExtendedBolus::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("id"), Index("isValid"), @@ -25,7 +27,8 @@ import java.util.* Index("pumpType"), Index("referenceId"), Index("timestamp") - ]) + ] +) data class ExtendedBolus( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -46,6 +49,20 @@ data class ExtendedBolus( require(duration > 0) } + private fun contentEqualsTo(other: ExtendedBolus): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + isEmulatingTempBasal == other.isEmulatingTempBasal && + duration == other.duration && + rate == other.rate + + fun onlyNsIdAdded(previous: ExtendedBolus): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + val rate: Double // in U/h get() = amount * (60 * 60 * 1000.0) / duration } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/Food.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/Food.kt index 762edf38c7..50a9601899 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/Food.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/Food.kt @@ -9,17 +9,20 @@ import info.nightscout.androidaps.database.TABLE_FOODS import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.interfaces.TraceableDBEntry -@Entity(tableName = TABLE_FOODS, +@Entity( + tableName = TABLE_FOODS, foreignKeys = [ForeignKey( entity = Food::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("id"), Index("nightscoutId"), Index("referenceId"), Index("isValid") - ]) + ] +) data class Food( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -46,7 +49,7 @@ data class Food( ) : TraceableDBEntry { - fun isEqual(other: Food): Boolean { + fun contentEqualsTo(other: Food): Boolean { if (isValid != other.isValid) return false if (portion != other.portion) return false if (carbs != other.carbs) return false @@ -60,6 +63,12 @@ data class Food( return unit == other.unit } + fun onlyNsIdAdded(previous: Food): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + fun copyFrom(other: Food) { isValid = other.isValid name = other.name diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt index d101681a7b..a292557866 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt @@ -45,14 +45,20 @@ data class GlucoseValue( ) : TraceableDBEntry, DBEntryWithTime { fun contentEqualsTo(other: GlucoseValue): Boolean = - timestamp == other.timestamp && + isValid == other.isValid && + timestamp == other.timestamp && utcOffset == other.utcOffset && raw == other.raw && value == other.value && trendArrow == other.trendArrow && noise == other.noise && - sourceSensor == other.sourceSensor && - isValid == other.isValid + sourceSensor == other.sourceSensor + + fun onlyNsIdAdded(previous: GlucoseValue): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null fun isRecordDeleted(other: GlucoseValue): Boolean = isValid && !other.isValid diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/OfflineEvent.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/OfflineEvent.kt index c2af9d5edb..d4f83b4737 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/OfflineEvent.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/OfflineEvent.kt @@ -11,18 +11,21 @@ import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration import info.nightscout.androidaps.database.interfaces.TraceableDBEntry import java.util.* -@Entity(tableName = TABLE_OFFLINE_EVENTS, +@Entity( + tableName = TABLE_OFFLINE_EVENTS, foreignKeys = [ForeignKey( entity = OfflineEvent::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("id"), Index("isValid"), Index("nightscoutId"), Index("referenceId"), Index("timestamp") - ]) + ] +) data class OfflineEvent( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -45,6 +48,12 @@ data class OfflineEvent( duration == other.duration && isValid == other.isValid + fun onlyNsIdAdded(previous: OfflineEvent): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + fun isRecordDeleted(other: OfflineEvent): Boolean = isValid && !other.isValid diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/ProfileSwitch.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/ProfileSwitch.kt index 569a895301..dfda513382 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/ProfileSwitch.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/ProfileSwitch.kt @@ -14,18 +14,21 @@ import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration import info.nightscout.androidaps.database.interfaces.TraceableDBEntry import java.util.* -@Entity(tableName = TABLE_PROFILE_SWITCHES, +@Entity( + tableName = TABLE_PROFILE_SWITCHES, foreignKeys = [ForeignKey( entity = ProfileSwitch::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("referenceId"), Index("timestamp"), Index("isValid"), Index("id"), Index("nightscoutId") - ]) + ] +) data class ProfileSwitch( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -50,6 +53,26 @@ data class ProfileSwitch( var insulinConfiguration: InsulinConfiguration ) : TraceableDBEntry, DBEntryWithTimeAndDuration { + private fun contentEqualsTo(other: ProfileSwitch): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + basalBlocks == other.basalBlocks && + isfBlocks == other.isfBlocks && + icBlocks == other.icBlocks && + targetBlocks == other.targetBlocks && + glucoseUnit == other.glucoseUnit && + profileName == other.profileName && + timeshift == other.timeshift && + percentage == other.percentage && + duration == other.duration + + fun onlyNsIdAdded(previous: ProfileSwitch): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + enum class GlucoseUnit { MGDL, MMOL; diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryBasal.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryBasal.kt index 14d1b876e6..8133f33635 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryBasal.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryBasal.kt @@ -48,6 +48,21 @@ data class TemporaryBasal( require(duration > 0) } + private fun contentEqualsTo(other: TemporaryBasal): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + isAbsolute == other.isAbsolute && + type == other.type && + duration == other.duration && + rate == other.rate + + fun onlyNsIdAdded(previous: TemporaryBasal): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + enum class Type { NORMAL, EMULATED_PUMP_SUSPEND, diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryTarget.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryTarget.kt index 7e6c2774fc..bec59a6da9 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryTarget.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/TemporaryTarget.kt @@ -5,25 +5,27 @@ import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.Index import androidx.room.PrimaryKey -import com.google.gson.annotations.SerializedName import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration import info.nightscout.androidaps.database.interfaces.TraceableDBEntry import java.util.* -@Entity(tableName = TABLE_TEMPORARY_TARGETS, +@Entity( + tableName = TABLE_TEMPORARY_TARGETS, foreignKeys = [ForeignKey( entity = TemporaryTarget::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("id"), Index("isValid"), Index("nightscoutId"), Index("referenceId"), Index("timestamp") - ]) + ] +) data class TemporaryTarget( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -53,22 +55,23 @@ data class TemporaryTarget( fun isRecordDeleted(other: TemporaryTarget): Boolean = isValid && !other.isValid + fun onlyNsIdAdded(previous: TemporaryTarget): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + enum class Reason(val text: String) { - @SerializedName("Custom") CUSTOM("Custom"), - @SerializedName("Hypo") HYPOGLYCEMIA("Hypo"), - @SerializedName("Activity") ACTIVITY("Activity"), - @SerializedName("Eating Soon") EATING_SOON("Eating Soon"), - @SerializedName("Automation") AUTOMATION("Automation"), - @SerializedName("Wear") WEAR("Wear") ; companion object { + fun fromString(reason: String?) = values().firstOrNull { it.text == reason } ?: CUSTOM } diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/TherapyEvent.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/TherapyEvent.kt index f930be4645..3884bcb47a 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/TherapyEvent.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/TherapyEvent.kt @@ -5,18 +5,19 @@ import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.Index import androidx.room.PrimaryKey -import com.google.gson.annotations.SerializedName import info.nightscout.androidaps.database.TABLE_THERAPY_EVENTS import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.interfaces.DBEntryWithTimeAndDuration import info.nightscout.androidaps.database.interfaces.TraceableDBEntry import java.util.* -@Entity(tableName = TABLE_THERAPY_EVENTS, +@Entity( + tableName = TABLE_THERAPY_EVENTS, foreignKeys = [ForeignKey( entity = TherapyEvent::class, parentColumns = ["id"], - childColumns = ["referenceId"])], + childColumns = ["referenceId"] + )], indices = [ Index("id"), Index("type"), @@ -24,7 +25,8 @@ import java.util.* Index("isValid"), Index("referenceId"), Index("timestamp") - ]) + ] +) data class TherapyEvent( @PrimaryKey(autoGenerate = true) override var id: Long = 0, @@ -45,18 +47,34 @@ data class TherapyEvent( var glucoseUnit: GlucoseUnit, ) : TraceableDBEntry, DBEntryWithTimeAndDuration { + private fun contentEqualsTo(other: TherapyEvent): Boolean = + isValid == other.isValid && + timestamp == other.timestamp && + utcOffset == other.utcOffset && + duration == other.duration && + type == other.type && + note == other.note && + enteredBy == other.enteredBy && + glucose == other.glucose && + glucoseType == other.glucoseType && + glucoseUnit == other.glucoseUnit + + fun onlyNsIdAdded(previous: TherapyEvent): Boolean = + previous.id != id && + contentEqualsTo(previous) && + previous.interfaceIDs.nightscoutId == null && + interfaceIDs.nightscoutId != null + enum class GlucoseUnit { MGDL, MMOL; + companion object } enum class MeterType(val text: String) { - @SerializedName("Finger") FINGER("Finger"), - @SerializedName("Sensor") SENSOR("Sensor"), - @SerializedName("Manual") MANUAL("Manual") ; @@ -69,99 +87,55 @@ data class TherapyEvent( @Suppress("unused") enum class Type(val text: String, val nsNative: Boolean = false) { - @SerializedName("Site Change") CANNULA_CHANGE("Site Change", nsNative = true), - @SerializedName("Insulin Change") INSULIN_CHANGE("Insulin Change", nsNative = true), - @SerializedName("Pump Battery Change") PUMP_BATTERY_CHANGE("Pump Battery Change", nsNative = true), - @SerializedName("Sensor Change") SENSOR_CHANGE("Sensor Change", nsNative = true), - @SerializedName("Sensor Start") SENSOR_STARTED("Sensor Start", nsNative = true), - @SerializedName("Sensor Stop") SENSOR_STOPPED("Sensor Stop", nsNative = true), - @SerializedName("BG Check") FINGER_STICK_BG_VALUE("BG Check", nsNative = true), - @SerializedName("Exercise") EXERCISE("Exercise", nsNative = true), - @SerializedName("Announcement") ANNOUNCEMENT("Announcement", nsNative = true), - @SerializedName("Question") QUESTION("Question", nsNative = true), - @SerializedName("Note") NOTE("Note", nsNative = true), - @SerializedName("OpenAPS Offline") APS_OFFLINE("OpenAPS Offline", nsNative = true), - @SerializedName("D.A.D. Alert") DAD_ALERT("D.A.D. Alert", nsNative = true), - @SerializedName("Mbg") NS_MBG("Mbg", nsNative = true), // Used but not as a Therapy Event (use constants only) - @SerializedName("Carb Correction") CARBS_CORRECTION("Carb Correction", nsNative = true), - @SerializedName("Bolus Wizard") BOLUS_WIZARD("Bolus Wizard", nsNative = true), - @SerializedName("Correction Bolus") CORRECTION_BOLUS("Correction Bolus", nsNative = true), - @SerializedName("Meal Bolus") MEAL_BOLUS("Meal Bolus", nsNative = true), - @SerializedName("Combo Bolus") COMBO_BOLUS("Combo Bolus", nsNative = true), - @SerializedName("Temporary Target") TEMPORARY_TARGET("Temporary Target", nsNative = true), - @SerializedName("Temporary Target Cancel") TEMPORARY_TARGET_CANCEL("Temporary Target Cancel", nsNative = true), - @SerializedName("Profile Switch") PROFILE_SWITCH("Profile Switch", nsNative = true), - @SerializedName("Snack Bolus") SNACK_BOLUS("Snack Bolus", nsNative = true), - @SerializedName("Temp Basal") TEMPORARY_BASAL("Temp Basal", nsNative = true), - @SerializedName("Temp Basal Start") TEMPORARY_BASAL_START("Temp Basal Start", nsNative = true), - @SerializedName("Temp Basal End") TEMPORARY_BASAL_END("Temp Basal End", nsNative = true), // Not supported by NS - @SerializedName("Tube Change") TUBE_CHANGE("Tube Change"), - @SerializedName("Falling Asleep") FALLING_ASLEEP("Falling Asleep"), - @SerializedName("Battery Empty") BATTERY_EMPTY("Battery Empty"), - @SerializedName("Reservoir Empty") RESERVOIR_EMPTY("Reservoir Empty"), - @SerializedName("Occlusion") OCCLUSION("Occlusion"), - @SerializedName("Pump Stopped") PUMP_STOPPED("Pump Stopped"), - @SerializedName("Pump Started") PUMP_STARTED("Pump Started"), - @SerializedName("Pump Paused") PUMP_PAUSED("Pump Paused"), - @SerializedName("Waking Up") WAKING_UP("Waking Up"), - @SerializedName("Sickness") SICKNESS("Sickness"), - @SerializedName("Stress") STRESS("Stress"), - @SerializedName("Pre Period") PRE_PERIOD("Pre Period"), - @SerializedName("Alcohol") ALCOHOL("Alcohol"), - @SerializedName("Cortisone") CORTISONE("Cortisone"), - @SerializedName("Feeling Low") FEELING_LOW("Feeling Low"), - @SerializedName("Feeling High") FEELING_HIGH("Feeling High"), - @SerializedName("Leaking Infusion Set") LEAKING_INFUSION_SET("Leaking Infusion Set"), // Default - @SerializedName("") NONE("") ; diff --git a/database/src/main/java/info/nightscout/androidaps/database/transactions/SyncNsFoodTransaction.kt b/database/src/main/java/info/nightscout/androidaps/database/transactions/SyncNsFoodTransaction.kt index 019c43a8b8..0ed3d70d93 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/transactions/SyncNsFoodTransaction.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/transactions/SyncNsFoodTransaction.kt @@ -17,7 +17,7 @@ class SyncNsFoodTransaction(private val food: Food) : Transaction