NSCv1,v3: improve sync

This commit is contained in:
Milos Kozak 2023-08-09 22:40:29 +02:00
parent 911c446190
commit fb94393c1c
21 changed files with 969 additions and 957 deletions

View file

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

View file

@ -21,22 +21,23 @@ interface DataSyncSelector {
val value: Any val value: Any
val id: Long val id: Long
var confirmed: Boolean
} }
data class PairTemporaryTarget(override val value: TemporaryTarget, override val id: Long) : DataPair data class PairTemporaryTarget(override val value: TemporaryTarget, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairGlucoseValue(override val value: GlucoseValue, override val id: Long) : DataPair data class PairGlucoseValue(override val value: GlucoseValue, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairTherapyEvent(override val value: TherapyEvent, override val id: Long) : DataPair data class PairTherapyEvent(override val value: TherapyEvent, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairFood(override val value: Food, override val id: Long) : DataPair data class PairFood(override val value: Food, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairBolus(override val value: Bolus, override val id: Long) : DataPair data class PairBolus(override val value: Bolus, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairCarbs(override val value: Carbs, override val id: Long) : DataPair data class PairCarbs(override val value: Carbs, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairBolusCalculatorResult(override val value: BolusCalculatorResult, override val id: Long) : DataPair data class PairBolusCalculatorResult(override val value: BolusCalculatorResult, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairTemporaryBasal(override val value: TemporaryBasal, override val id: Long) : DataPair data class PairTemporaryBasal(override val value: TemporaryBasal, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairExtendedBolus(override val value: ExtendedBolus, override val id: Long) : DataPair data class PairExtendedBolus(override val value: ExtendedBolus, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairProfileSwitch(override val value: ProfileSwitch, override val id: Long) : DataPair data class PairProfileSwitch(override val value: ProfileSwitch, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairEffectiveProfileSwitch(override val value: EffectiveProfileSwitch, override val id: Long) : DataPair data class PairEffectiveProfileSwitch(override val value: EffectiveProfileSwitch, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairOfflineEvent(override val value: OfflineEvent, override val id: Long) : DataPair data class PairOfflineEvent(override val value: OfflineEvent, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairProfileStore(override val value: JSONObject, override val id: Long) : DataPair data class PairProfileStore(override val value: JSONObject, override val id: Long, override var confirmed: Boolean = false) : DataPair
data class PairDeviceStatus(override val value: DeviceStatus, override val id: Long) : DataPair data class PairDeviceStatus(override val value: DeviceStatus, override val id: Long, override var confirmed: Boolean = false) : DataPair
fun queueSize(): Long fun queueSize(): Long

View file

@ -1,46 +0,0 @@
package info.nightscout.interfaces.sync
interface DataSyncSelectorV1 : DataSyncSelector {
fun confirmLastBolusIdIfGreater(lastSynced: Long)
suspend fun processChangedBoluses()
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
suspend fun processChangedCarbs()
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
suspend fun processChangedBolusCalculatorResults()
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
suspend fun processChangedTempTargets()
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
suspend fun processChangedGlucoseValues()
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
suspend fun processChangedTherapyEvents()
fun confirmLastFoodIdIfGreater(lastSynced: Long)
suspend fun processChangedFoods()
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
suspend fun processChangedDeviceStatuses()
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
suspend fun processChangedTemporaryBasals()
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
suspend fun processChangedExtendedBoluses()
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
suspend fun processChangedProfileSwitches()
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
suspend fun processChangedEffectiveProfileSwitches()
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
suspend fun processChangedOfflineEvents()
fun confirmLastProfileStore(lastSynced: Long)
suspend fun processChangedProfileStore()
}

View file

@ -1,3 +0,0 @@
package info.nightscout.interfaces.sync
interface DataSyncSelectorV3 : DataSyncSelector

View file

@ -5,6 +5,7 @@ import androidx.room.Entity
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import info.nightscout.database.entities.embedments.InterfaceIDs import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.database.entities.interfaces.DBEntry
import info.nightscout.database.entities.interfaces.DBEntryWithTime import info.nightscout.database.entities.interfaces.DBEntryWithTime
import java.util.TimeZone import java.util.TimeZone
@ -17,7 +18,7 @@ import java.util.TimeZone
]) ])
data class DeviceStatus( data class DeviceStatus(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
var id: Long = 0, override var id: Long = 0,
@Embedded @Embedded
var interfaceIDs_backing: InterfaceIDs? = null, var interfaceIDs_backing: InterfaceIDs? = null,
override var timestamp: Long, override var timestamp: Long,
@ -31,7 +32,7 @@ data class DeviceStatus(
var isCharging: Boolean?, var isCharging: Boolean?,
var configuration: String? = null var configuration: String? = null
) : DBEntryWithTime { ) : DBEntry, DBEntryWithTime {
var interfaceIDs: InterfaceIDs var interfaceIDs: InterfaceIDs
get() { get() {

View file

@ -254,6 +254,7 @@ import kotlin.math.roundToInt
fun insert(word: UserEntry) { fun insert(word: UserEntry) {
database.userEntryDao.insert(word) database.userEntryDao.insert(word)
changeSubject.onNext(mutableListOf(word)) // Not TraceableDao
} }
// PROFILE SWITCH // PROFILE SWITCH
@ -712,8 +713,10 @@ import kotlin.math.roundToInt
database.bolusCalculatorResultDao.getLastId() database.bolusCalculatorResultDao.getLastId()
// DEVICE STATUS // DEVICE STATUS
fun insert(deviceStatus: DeviceStatus): Long = fun insert(deviceStatus: DeviceStatus) {
database.deviceStatusDao.insert(deviceStatus) database.deviceStatusDao.insert(deviceStatus)
changeSubject.onNext(mutableListOf(deviceStatus)) // Not TraceableDao
}
/* /*
* returns a Pair of the next entity to sync and the ID of the "update". * returns a Pair of the next entity to sync and the ID of the "update".
@ -727,10 +730,6 @@ import kotlin.math.roundToInt
database.deviceStatusDao.getNextModifiedOrNewAfter(id) database.deviceStatusDao.getNextModifiedOrNewAfter(id)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
fun getModifiedDeviceStatusDataFromId(lastId: Long): Single<List<DeviceStatus>> =
database.deviceStatusDao.getModifiedFrom(lastId)
.subscribeOn(Schedulers.io())
fun getLastDeviceStatusId(): Long? = fun getLastDeviceStatusId(): Long? =
database.deviceStatusDao.getLastId() database.deviceStatusDao.getLastId()

View file

@ -3,6 +3,7 @@ package info.nightscout.implementation.db
import android.content.Context import android.content.Context
import info.nightscout.database.entities.Bolus import info.nightscout.database.entities.Bolus
import info.nightscout.database.entities.Carbs import info.nightscout.database.entities.Carbs
import info.nightscout.database.entities.DeviceStatus
import info.nightscout.database.entities.EffectiveProfileSwitch import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.database.entities.ExtendedBolus import info.nightscout.database.entities.ExtendedBolus
import info.nightscout.database.entities.Food import info.nightscout.database.entities.Food
@ -15,6 +16,7 @@ import info.nightscout.database.entities.TherapyEvent
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventDeviceStatusChange
import info.nightscout.rx.events.EventEffectiveProfileSwitchChanged import info.nightscout.rx.events.EventEffectiveProfileSwitchChanged
import info.nightscout.rx.events.EventExtendedBolusChange import info.nightscout.rx.events.EventExtendedBolusChange
import info.nightscout.rx.events.EventFoodDatabaseChanged import info.nightscout.rx.events.EventFoodDatabaseChanged
@ -109,5 +111,9 @@ class CompatDBHelper @Inject constructor(
aapsLogger.debug(LTag.DATABASE, "Firing EventOfflineChange $oe") aapsLogger.debug(LTag.DATABASE, "Firing EventOfflineChange $oe")
rxBus.send(EventOfflineChange()) rxBus.send(EventOfflineChange())
} }
it.filterIsInstance<DeviceStatus>().firstOrNull()?.let { ds ->
aapsLogger.debug(LTag.DATABASE, "Firing EventDeviceStatusChange $ds")
rxBus.send(EventDeviceStatusChange())
}
} }
} }

View file

@ -11,12 +11,9 @@ import info.nightscout.interfaces.XDripBroadcast
import info.nightscout.interfaces.nsclient.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.sync.DataSyncSelectorV1
import info.nightscout.interfaces.sync.DataSyncSelectorV3
import info.nightscout.interfaces.sync.DataSyncSelectorXdrip import info.nightscout.interfaces.sync.DataSyncSelectorXdrip
import info.nightscout.plugins.sync.nsShared.NSClientFragment import info.nightscout.plugins.sync.nsShared.NSClientFragment
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
import info.nightscout.plugins.sync.nsclient.DataSyncSelectorV1Impl
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatusImpl import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatusImpl
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl
import info.nightscout.plugins.sync.nsclient.services.NSClientService import info.nightscout.plugins.sync.nsclient.services.NSClientService
@ -24,8 +21,14 @@ import info.nightscout.plugins.sync.nsclient.workers.NSClientAddAckWorker
import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker
import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker
import info.nightscout.plugins.sync.nsclient.workers.NSClientUpdateRemoveAckWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientUpdateRemoveAckWorker
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3Impl import info.nightscout.plugins.sync.nsclientV3.workers.DataSyncWorker
import info.nightscout.plugins.sync.nsclientV3.workers.* import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadDeviceStatusWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadFoodsWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadProfileStoreWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadTreatmentsWorker
import info.nightscout.plugins.sync.tidepool.TidepoolFragment import info.nightscout.plugins.sync.tidepool.TidepoolFragment
import info.nightscout.plugins.sync.xdrip.DataSyncSelectorXdripImpl import info.nightscout.plugins.sync.xdrip.DataSyncSelectorXdripImpl
import info.nightscout.plugins.sync.xdrip.XdripFragment import info.nightscout.plugins.sync.xdrip.XdripFragment
@ -75,8 +78,6 @@ abstract class SyncModule {
@Binds fun bindProcessedDeviceStatusData(processedDeviceStatusDataImpl: ProcessedDeviceStatusDataImpl): ProcessedDeviceStatusData @Binds fun bindProcessedDeviceStatusData(processedDeviceStatusDataImpl: ProcessedDeviceStatusDataImpl): ProcessedDeviceStatusData
@Binds fun bindNSSettingsStatus(nsSettingsStatusImpl: NSSettingsStatusImpl): NSSettingsStatus @Binds fun bindNSSettingsStatus(nsSettingsStatusImpl: NSSettingsStatusImpl): NSSettingsStatus
@Binds fun bindDataSyncSelectorV1Interface(dataSyncSelectorV1Impl: DataSyncSelectorV1Impl): DataSyncSelectorV1
@Binds fun bindDataSyncSelectorV3Interface(dataSyncSelectorV3Impl: DataSyncSelectorV3Impl): DataSyncSelectorV3
@Binds fun bindDataSyncSelectorXdripInterface(dataSyncSelectorXdripImpl: DataSyncSelectorXdripImpl): DataSyncSelectorXdrip @Binds fun bindDataSyncSelectorXdripInterface(dataSyncSelectorXdripImpl: DataSyncSelectorXdripImpl): DataSyncSelectorXdrip
@Binds fun bindStoreDataForDb(storeDataForDbImpl: StoreDataForDbImpl): StoreDataForDb @Binds fun bindStoreDataForDb(storeDataForDbImpl: StoreDataForDbImpl): StoreDataForDb
@Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XdripPlugin): XDripBroadcast @Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XdripPlugin): XDripBroadcast

View file

@ -123,7 +123,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
nsClientPlugin?.listLog?.let { nsClientPlugin?.listLog?.let {
synchronized(it) { synchronized(it) {
it.clear() it.clear()
_binding?.recyclerview?.swapAdapter(RecyclerViewAdapter(it), true) updateLog()
} }
} }
true true
@ -211,6 +211,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
.subscribe({ updateStatus() }, fabricPrivacy::logException) .subscribe({ updateStatus() }, fabricPrivacy::logException)
updateStatus() updateStatus()
updateQueue() updateQueue()
updateLog()
} }
@Synchronized @Synchronized
@ -231,6 +232,9 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
binding.status.text = nsClientPlugin?.status binding.status.text = nsClientPlugin?.status
} }
private fun updateLog() {
_binding?.recyclerview?.swapAdapter(RecyclerViewAdapter(nsClientPlugin?.listLog ?: arrayListOf()), true)
}
private inner class RecyclerViewAdapter(private var logList: List<EventNSClientNewLog>) : RecyclerView.Adapter<RecyclerViewAdapter.NsClientLogViewHolder>() { private inner class RecyclerViewAdapter(private var logList: List<EventNSClientNewLog>) : RecyclerView.Adapter<RecyclerViewAdapter.NsClientLogViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NsClientLogViewHolder = override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NsClientLogViewHolder =

View file

@ -0,0 +1,807 @@
package info.nightscout.plugins.sync.nsclient
import info.nightscout.core.utils.waitMillis
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DataSyncSelectorV1 @Inject constructor(
private val sp: SP,
private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil,
private val profileFunction: ProfileFunction,
private val activePlugin: ActivePlugin,
private val appRepository: AppRepository,
private val rxBus: RxBus
) : DataSyncSelector {
private var scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
class QueueCounter(
var bolusesRemaining: Long = -1L,
var carbsRemaining: Long = -1L,
var bcrRemaining: Long = -1L,
var ttsRemaining: Long = -1L,
var foodsRemaining: Long = -1L,
var gvsRemaining: Long = -1L,
var tesRemaining: Long = -1L,
var dssRemaining: Long = -1L,
var tbrsRemaining: Long = -1L,
var ebsRemaining: Long = -1L,
var pssRemaining: Long = -1L,
var epssRemaining: Long = -1L,
var oesRemaining: Long = -1L
) {
fun size(): Long =
bolusesRemaining +
carbsRemaining +
bcrRemaining +
ttsRemaining +
foodsRemaining +
gvsRemaining +
tesRemaining +
dssRemaining +
tbrsRemaining +
ebsRemaining +
pssRemaining +
epssRemaining +
oesRemaining
}
private val queueCounter = QueueCounter()
private val isPaused get() = sp.getBoolean(R.string.key_ns_paused, false)
override fun queueSize(): Long = queueCounter.size()
private var running = false
private val sync = Any()
override suspend fun doUpload() {
synchronized(sync) {
if (running) {
rxBus.send(EventNSClientNewLog("● RUN", "Already running"))
return
}
running = true
}
rxBus.send(EventNSClientUpdateGuiStatus())
if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) {
queueCounter.bolusesRemaining = (appRepository.getLastBolusId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
queueCounter.carbsRemaining = (appRepository.getLastCarbsId() ?: 0L) - sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
queueCounter.bcrRemaining = (appRepository.getLastBolusCalculatorResultId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
queueCounter.ttsRemaining = (appRepository.getLastTempTargetId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
queueCounter.foodsRemaining = (appRepository.getLastFoodId() ?: 0L) - sp.getLong(R.string.key_ns_food_last_synced_id, 0)
queueCounter.gvsRemaining = (appRepository.getLastGlucoseValueId() ?: 0L) - sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
queueCounter.tesRemaining = (appRepository.getLastTherapyEventId() ?: 0L) - sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
queueCounter.dssRemaining = (appRepository.getLastDeviceStatusId() ?: 0L) - sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
queueCounter.tbrsRemaining = (appRepository.getLastTemporaryBasalId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
queueCounter.ebsRemaining = (appRepository.getLastExtendedBolusId() ?: 0L) - sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
queueCounter.pssRemaining = (appRepository.getLastProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
queueCounter.epssRemaining = (appRepository.getLastEffectiveProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
queueCounter.oesRemaining = (appRepository.getLastOfflineEventId() ?: 0L) - sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
rxBus.send(EventNSClientUpdateGuiQueue())
val boluses = scope.async { processChangedBoluses() }
val carbs = scope.async { processChangedCarbs() }
val bcs = scope.async { processChangedBolusCalculatorResults() }
val tbs = scope.async { processChangedTemporaryBasals() }
val ebs = scope.async { processChangedExtendedBoluses() }
val pss = scope.async { processChangedProfileSwitches() }
val epss = scope.async { processChangedEffectiveProfileSwitches() }
val gvs = scope.async { processChangedGlucoseValues() }
val tts = scope.async { processChangedTempTargets() }
val foods = scope.async { processChangedFoods() }
val tes = scope.async { processChangedTherapyEvents() }
val dss = scope.async { processChangedDeviceStatuses() }
val oes = scope.async { processChangedOfflineEvents() }
val ps = scope.async { processChangedProfileStore() }
boluses.await()
carbs.await()
bcs.await()
tbs.await()
ebs.await()
pss.await()
epss.await()
gvs.await()
tts.await()
foods.await()
tes.await()
dss.await()
oes.await()
ps.await()
}
rxBus.send(EventNSClientUpdateGuiStatus())
running = false
}
override fun resetToNextFullSync() {
sp.remove(R.string.key_ns_glucose_value_last_synced_id)
sp.remove(R.string.key_ns_temporary_basal_last_synced_id)
sp.remove(R.string.key_ns_temporary_target_last_synced_id)
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
sp.remove(R.string.key_ns_food_last_synced_id)
sp.remove(R.string.key_ns_bolus_last_synced_id)
sp.remove(R.string.key_ns_carbs_last_synced_id)
sp.remove(R.string.key_ns_bolus_calculator_result_last_synced_id)
sp.remove(R.string.key_ns_therapy_event_last_synced_id)
sp.remove(R.string.key_ns_profile_switch_last_synced_id)
sp.remove(R.string.key_ns_effective_profile_switch_last_synced_id)
sp.remove(R.string.key_ns_offline_event_last_synced_id)
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
val lastDeviceStatusDbId = appRepository.getLastDeviceStatusId()
if (lastDeviceStatusDbId != null) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbId)
else sp.remove(R.string.key_ns_device_status_last_synced_id)
}
private fun confirmLastBolusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Bolus data sync from $lastSynced")
sp.putLong(R.string.key_ns_bolus_last_synced_id, lastSynced)
}
}
private suspend fun processChangedBoluses() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastBolusId() ?: 0L
var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_bolus_last_synced_id, 0)
startId = 0
}
queueCounter.bolusesRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus ->
aapsLogger.info(LTag.NSCLIENT, "Loading Bolus data Start: $startId ${bolus.first} forID: ${bolus.second.id} ")
val dataPair = DataSyncSelector.PairBolus(bolus.first, bolus.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
bolus.first.id == bolus.second.id && bolus.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Loaded from NS: ${bolus.second.id} ")
// only NsId changed, no need to upload
bolus.first.onlyNsIdAdded(bolus.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Only NS id changed: ${bolus.second.id} ")
// without nsId = create new
bolus.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, " $startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update if it's modified record
bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastBolusIdIfGreater(bolus.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastCarbsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Carbs data sync from $lastSynced")
sp.putLong(R.string.key_ns_carbs_last_synced_id, lastSynced)
}
}
private suspend fun processChangedCarbs() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastCarbsId() ?: 0L
var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_carbs_last_synced_id, 0)
startId = 0
}
queueCounter.carbsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb ->
aapsLogger.info(LTag.NSCLIENT, "Loading Carbs data Start: $startId ${carb.first} forID: ${carb.second.id} ")
val dataPair = DataSyncSelector.PairCarbs(carb.first, carb.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
carb.first.id == carb.second.id && carb.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Loaded from NS: ${carb.second.id} ")
// only NsId changed, no need to upload
carb.first.onlyNsIdAdded(carb.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Only NS id changed ID: ${carb.second.id} ")
// without nsId = create new
carb.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update if it's modified record
carb.first.interfaceIDs.nightscoutId != null && carb.first.id != carb.second.id -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastCarbsIdIfGreater(carb.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting BolusCalculatorResult data sync from $lastSynced")
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, lastSynced)
}
}
private suspend fun processChangedBolusCalculatorResults() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastBolusCalculatorResultId() ?: 0L
var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
startId = 0
}
queueCounter.bcrRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult ->
aapsLogger.info(LTag.NSCLIENT, "Loading BolusCalculatorResult data Start: $startId ${bolusCalculatorResult.first} forID: ${bolusCalculatorResult.second.id} ")
val dataPair = DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
bolusCalculatorResult.first.id == bolusCalculatorResult.second.id && bolusCalculatorResult.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Loaded from NS: ${bolusCalculatorResult.second.id} ")
// only NsId changed, no need to upload
bolusCalculatorResult.first.onlyNsIdAdded(bolusCalculatorResult.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Only NS id changed ID: ${bolusCalculatorResult.second.id} ")
// without nsId = create new
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update if it's modified record
bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryTarget data sync from $lastSynced")
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, lastSynced)
}
}
private suspend fun processChangedTempTargets() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastTempTargetId() ?: 0L
var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, 0)
startId = 0
}
queueCounter.ttsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt ->
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryTarget data Start: $startId ${tt.first} forID: ${tt.second.id} ")
val dataPair = DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
tt.first.id == tt.second.id && tt.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Loaded from NS: ${tt.second.id} ")
// only NsId changed, no need to upload
tt.first.onlyNsIdAdded(tt.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Only NS id changed ID: ${tt.second.id} ")
// without nsId = create new
tt.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// existing with nsId = update
tt.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastTempTargetsIdIfGreater(tt.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastFoodIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_food_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Food data sync from $lastSynced")
sp.putLong(R.string.key_ns_food_last_synced_id, lastSynced)
}
}
private suspend fun processChangedFoods() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastFoodId() ?: 0L
var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_food_last_synced_id, 0)
startId = 0
}
queueCounter.foodsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food ->
aapsLogger.info(LTag.NSCLIENT, "Loading Food data Start: $startId ${food.first} forID: ${food.second.id} ")
val dataPair = DataSyncSelector.PairFood(food.first, food.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
food.first.id == food.second.id && food.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Loaded from NS: ${food.second.id} ")
// only NsId changed, no need to upload
food.first.onlyNsIdAdded(food.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Only NS id changed ID: ${food.second.id} ")
// without nsId = create new
food.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("food", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update
food.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("food", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastFoodIdIfGreater(food.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting GlucoseValue data sync from $lastSynced")
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, lastSynced)
}
}
private suspend fun processChangedGlucoseValues() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastGlucoseValueId() ?: 0L
var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, 0)
startId = 0
}
queueCounter.gvsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv ->
aapsLogger.info(LTag.NSCLIENT, "Loading GlucoseValue data Start: $startId ${gv.first} forID: ${gv.second.id} ")
val dataPair = DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id)
if (activePlugin.activeBgSource.shouldUploadToNs(gv.first)) {
when {
// new record with existing NS id => must be coming from NS => ignore
gv.first.id == gv.second.id && gv.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Loaded from NS: ${gv.second.id} ")
// only NsId changed, no need to upload
gv.first.onlyNsIdAdded(gv.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Only NS id changed ID: ${gv.second.id} ")
// without nsId = create new
gv.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("entries", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update
else -> {// gv.first.interfaceIDs.nightscoutId != null
activePlugin.activeNsClient?.nsUpdate("entries", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
}
if (cont) confirmLastGlucoseValueIdIfGreater(gv.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TherapyEvents data sync from $lastSynced")
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, lastSynced)
}
}
private suspend fun processChangedTherapyEvents() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastTherapyEventId() ?: 0L
var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, 0)
startId = 0
}
queueCounter.tesRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te ->
aapsLogger.info(LTag.NSCLIENT, "Loading TherapyEvents data Start: $startId ${te.first} forID: ${te.second.id} ")
val dataPair = DataSyncSelector.PairTherapyEvent(te.first, te.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
te.first.id == te.second.id && te.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Loaded from NS: ${te.second.id} ")
// only NsId changed, no need to upload
te.first.onlyNsIdAdded(te.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Only NS id changed ID: ${te.second.id} ")
// without nsId = create new
te.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// nsId = update
te.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastTherapyEventIdIfGreater(te.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting DeviceStatus data sync from $lastSynced")
sp.putLong(R.string.key_ns_device_status_last_synced_id, lastSynced)
}
}
private suspend fun processChangedDeviceStatuses() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_device_status_last_synced_id, 0)
startId = 0
}
queueCounter.dssRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus")
val dataPair = DataSyncSelector.PairDeviceStatus(deviceStatus, lastDbId)
activePlugin.activeNsClient?.nsAdd("devicestatus", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
if (cont) confirmLastDeviceStatusIdIfGreater(deviceStatus.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryBasal data sync from $lastSynced")
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, lastSynced)
}
}
private suspend fun processChangedTemporaryBasals() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastTemporaryBasalId() ?: 0L
var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
startId = 0
}
queueCounter.tbrsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb ->
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryBasal data Start: $startId ${tb.first} forID: ${tb.second.id} ")
val dataPair = DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id)
val profile = profileFunction.getProfile(tb.first.timestamp)
if (profile != null) {
when {
// new record with existing NS id => must be coming from NS => ignore
tb.first.id == tb.second.id && tb.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Loaded from NS: ${tb.second.id} ")
// only NsId changed, no need to upload
tb.first.onlyNsIdAdded(tb.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Only NS id changed ID: ${tb.second.id} ")
// without nsId = create new
tb.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId", profile)
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update
tb.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId", profile)
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
} else aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. No profile: ${tb.second.id} ")
if (cont) confirmLastTemporaryBasalIdIfGreater(tb.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting ExtendedBolus data sync from $lastSynced")
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, lastSynced)
}
}
private suspend fun processChangedExtendedBoluses() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastExtendedBolusId() ?: 0L
var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
startId = 0
}
queueCounter.ebsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb ->
aapsLogger.info(LTag.NSCLIENT, "Loading ExtendedBolus data Start: $startId ${eb.first} forID: ${eb.second.id} ")
val dataPair = DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id)
val profile = profileFunction.getProfile(eb.first.timestamp)
if (profile != null) {
when {
// new record with existing NS id => must be coming from NS => ignore
eb.first.id == eb.second.id && eb.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Loaded from NS: ${eb.second.id} ")
// only NsId changed, no need to upload
eb.first.onlyNsIdAdded(eb.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Only NS id changed ID: ${eb.second.id} ")
// without nsId = create new
eb.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId", profile)
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update
eb.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId", profile)
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
} else aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. No profile: ${eb.second.id} ")
if (cont) confirmLastExtendedBolusIdIfGreater(eb.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting ProfileSwitch data sync from $lastSynced")
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, lastSynced)
}
}
private suspend fun processChangedProfileSwitches() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastProfileSwitchId() ?: 0L
var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, 0)
startId = 0
}
queueCounter.pssRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps ->
aapsLogger.info(LTag.NSCLIENT, "Loading ProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
val dataPair = DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Loaded from NS: ${ps.second.id} ")
// only NsId changed, no need to upload
ps.first.onlyNsIdAdded(ps.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
// without nsId = create new
ps.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update
ps.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastProfileSwitchIdIfGreater(ps.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting EffectiveProfileSwitch data sync from $lastSynced")
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, lastSynced)
}
}
private suspend fun processChangedEffectiveProfileSwitches() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastEffectiveProfileSwitchId() ?: 0L
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
startId = 0
}
queueCounter.epssRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps ->
aapsLogger.info(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
val dataPair = DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Loaded from NS: ${ps.second.id} ")
// only NsId changed, no need to upload
ps.first.onlyNsIdAdded(ps.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
// without nsId = create new
ps.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// with nsId = update
ps.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced")
sp.putLong(R.string.key_ns_offline_event_last_synced_id, lastSynced)
}
}
private suspend fun processChangedOfflineEvents() {
var cont = true
while (cont) {
if (isPaused) return
val lastDbId = appRepository.getLastOfflineEventId() ?: 0L
var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_offline_event_last_synced_id, 0)
startId = 0
}
queueCounter.oesRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe ->
aapsLogger.info(LTag.NSCLIENT, "Loading OfflineEvent data Start: $startId ${oe.first} forID: ${oe.second.id} ")
val dataPair = DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id)
when {
// new record with existing NS id => must be coming from NS => ignore
oe.first.id == oe.second.id && oe.first.interfaceIDs.nightscoutId != null ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Loaded from NS: ${oe.second.id} ")
// only NsId changed, no need to upload
oe.first.onlyNsIdAdded(oe.second) ->
aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Only NS id changed ID: ${oe.second.id} ")
// without nsId = create new
oe.first.interfaceIDs.nightscoutId == null -> {
activePlugin.activeNsClient?.nsAdd("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
// existing with nsId = update
oe.first.interfaceIDs.nightscoutId != null -> {
activePlugin.activeNsClient?.nsUpdate("treatments", dataPair, "$startId/$lastDbId")
synchronized(dataPair) { dataPair.waitMillis(60000) }
cont = dataPair.confirmed
}
}
if (cont) confirmLastOfflineEventIdIfGreater(oe.second.id)
} ?: run {
cont = false
}
}
}
private fun confirmLastProfileStore(lastSynced: Long) {
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
}
private suspend fun processChangedProfileStore() {
if (isPaused) return
val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0)
val lastChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
if (lastChange == 0L) return
if (lastChange > lastSync) {
if (activePlugin.activeProfileSource.profile?.allProfilesValid != true) return
val profileStore = activePlugin.activeProfileSource.profile
val profileJson = profileStore?.data ?: return
// add for v3
if (JsonHelper.safeGetLongAllowNull(profileJson, "date") == null)
profileJson.put("date", profileStore.getStartDate())
val dataPair = DataSyncSelector.PairProfileStore(profileJson, dateUtil.now())
activePlugin.activeNsClient?.nsAdd("profile", dataPair, "")
synchronized(dataPair) { dataPair.waitMillis(60000) }
val now = dateUtil.now()
val cont = dataPair.confirmed
if (cont) confirmLastProfileStore(now)
}
}
}

View file

@ -1,737 +0,0 @@
package info.nightscout.plugins.sync.nsclient
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.DataSyncSelectorV1
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DataSyncSelectorV1Impl @Inject constructor(
private val sp: SP,
private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil,
private val profileFunction: ProfileFunction,
private val activePlugin: ActivePlugin,
private val appRepository: AppRepository,
private val rxBus: RxBus
) : DataSyncSelectorV1 {
class QueueCounter(
var bolusesRemaining: Long = -1L,
var carbsRemaining: Long = -1L,
var bcrRemaining: Long = -1L,
var ttsRemaining: Long = -1L,
var foodsRemaining: Long = -1L,
var gvsRemaining: Long = -1L,
var tesRemaining: Long = -1L,
var dssRemaining: Long = -1L,
var tbrsRemaining: Long = -1L,
var ebsRemaining: Long = -1L,
var pssRemaining: Long = -1L,
var epssRemaining: Long = -1L,
var oesRemaining: Long = -1L
) {
fun size(): Long =
bolusesRemaining +
carbsRemaining +
bcrRemaining +
ttsRemaining +
foodsRemaining +
gvsRemaining +
tesRemaining +
dssRemaining +
tbrsRemaining +
ebsRemaining +
pssRemaining +
epssRemaining +
oesRemaining
}
private val queueCounter = QueueCounter()
private val isPaused get() = sp.getBoolean(R.string.key_ns_paused, false)
override fun queueSize(): Long = queueCounter.size()
override suspend fun doUpload() {
rxBus.send(EventNSClientUpdateGuiStatus())
if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) {
queueCounter.bolusesRemaining = (appRepository.getLastBolusId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
queueCounter.carbsRemaining = (appRepository.getLastCarbsId() ?: 0L) - sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
queueCounter.bcrRemaining = (appRepository.getLastBolusCalculatorResultId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
queueCounter.ttsRemaining = (appRepository.getLastTempTargetId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
queueCounter.foodsRemaining = (appRepository.getLastFoodId() ?: 0L) - sp.getLong(R.string.key_ns_food_last_synced_id, 0)
queueCounter.gvsRemaining = (appRepository.getLastGlucoseValueId() ?: 0L) - sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
queueCounter.tesRemaining = (appRepository.getLastTherapyEventId() ?: 0L) - sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
queueCounter.dssRemaining = (appRepository.getLastDeviceStatusId() ?: 0L) - sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
queueCounter.tbrsRemaining = (appRepository.getLastTemporaryBasalId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
queueCounter.ebsRemaining = (appRepository.getLastExtendedBolusId() ?: 0L) - sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
queueCounter.pssRemaining = (appRepository.getLastProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
queueCounter.epssRemaining = (appRepository.getLastEffectiveProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
queueCounter.oesRemaining = (appRepository.getLastOfflineEventId() ?: 0L) - sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
rxBus.send(EventNSClientUpdateGuiQueue())
processChangedBoluses()
processChangedCarbs()
processChangedBolusCalculatorResults()
processChangedTemporaryBasals()
processChangedExtendedBoluses()
processChangedProfileSwitches()
processChangedEffectiveProfileSwitches()
processChangedGlucoseValues()
processChangedTempTargets()
processChangedFoods()
processChangedTherapyEvents()
processChangedDeviceStatuses()
processChangedOfflineEvents()
processChangedProfileStore()
}
rxBus.send(EventNSClientUpdateGuiStatus())
}
override fun resetToNextFullSync() {
sp.remove(R.string.key_ns_glucose_value_last_synced_id)
sp.remove(R.string.key_ns_temporary_basal_last_synced_id)
sp.remove(R.string.key_ns_temporary_target_last_synced_id)
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
sp.remove(R.string.key_ns_food_last_synced_id)
sp.remove(R.string.key_ns_bolus_last_synced_id)
sp.remove(R.string.key_ns_carbs_last_synced_id)
sp.remove(R.string.key_ns_bolus_calculator_result_last_synced_id)
sp.remove(R.string.key_ns_therapy_event_last_synced_id)
sp.remove(R.string.key_ns_profile_switch_last_synced_id)
sp.remove(R.string.key_ns_effective_profile_switch_last_synced_id)
sp.remove(R.string.key_ns_offline_event_last_synced_id)
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
val lastDeviceStatusDbId = appRepository.getLastDeviceStatusId()
if (lastDeviceStatusDbId != null) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbId)
else sp.remove(R.string.key_ns_device_status_last_synced_id)
}
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Bolus data sync from $lastSynced")
sp.putLong(R.string.key_ns_bolus_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedBoluses() {
if (isPaused) return
val lastDbId = appRepository.getLastBolusId() ?: 0L
var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_bolus_last_synced_id, 0)
startId = 0
}
queueCounter.bolusesRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus ->
aapsLogger.info(LTag.NSCLIENT, "Loading Bolus data Start: $startId ${bolus.first} forID: ${bolus.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
bolus.first.id == bolus.second.id && bolus.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Loaded from NS: ${bolus.second.id} ")
confirmLastBolusIdIfGreater(bolus.second.id)
processChangedBoluses()
return
}
// only NsId changed, no need to upload
bolus.first.onlyNsIdAdded(bolus.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Only NS id changed: ${bolus.second.id} ")
confirmLastBolusIdIfGreater(bolus.second.id)
processChangedBoluses()
return
}
// without nsId = create new
bolus.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), " $startId/$lastDbId")
// with nsId = update if it's modified record
bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastCarbsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Carbs data sync from $lastSynced")
sp.putLong(R.string.key_ns_carbs_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedCarbs() {
if (isPaused) return
val lastDbId = appRepository.getLastCarbsId() ?: 0L
var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_carbs_last_synced_id, 0)
startId = 0
}
queueCounter.carbsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb ->
aapsLogger.info(LTag.NSCLIENT, "Loading Carbs data Start: $startId ${carb.first} forID: ${carb.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
carb.first.id == carb.second.id && carb.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Loaded from NS: ${carb.second.id} ")
confirmLastCarbsIdIfGreater(carb.second.id)
processChangedCarbs()
return
}
// only NsId changed, no need to upload
carb.first.onlyNsIdAdded(carb.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Only NS id changed ID: ${carb.second.id} ")
confirmLastCarbsIdIfGreater(carb.second.id)
processChangedCarbs()
return
}
// without nsId = create new
carb.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId")
// with nsId = update if it's modified record
carb.first.interfaceIDs.nightscoutId != null && carb.first.id != carb.second.id ->
activePlugin.activeNsClient?.nsUpdate(
"treatments",
DataSyncSelector.PairCarbs(carb.first, carb.second.id),
"$startId/$lastDbId"
)
}
return
}
}
override fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting BolusCalculatorResult data sync from $lastSynced")
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedBolusCalculatorResults() {
if (isPaused) return
val lastDbId = appRepository.getLastBolusCalculatorResultId() ?: 0L
var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
startId = 0
}
queueCounter.bcrRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult ->
aapsLogger.info(LTag.NSCLIENT, "Loading BolusCalculatorResult data Start: $startId ${bolusCalculatorResult.first} forID: ${bolusCalculatorResult.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
bolusCalculatorResult.first.id == bolusCalculatorResult.second.id && bolusCalculatorResult.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Loaded from NS: ${bolusCalculatorResult.second.id} ")
confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id)
processChangedBolusCalculatorResults()
return
}
// only NsId changed, no need to upload
bolusCalculatorResult.first.onlyNsIdAdded(bolusCalculatorResult.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Only NS id changed ID: ${bolusCalculatorResult.second.id} ")
confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id)
processChangedBolusCalculatorResults()
return
}
// without nsId = create new
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId")
// with nsId = update if it's modified record
bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryTarget data sync from $lastSynced")
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedTempTargets() {
if (isPaused) return
val lastDbId = appRepository.getLastTempTargetId() ?: 0L
var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, 0)
startId = 0
}
queueCounter.ttsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt ->
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryTarget data Start: $startId ${tt.first} forID: ${tt.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
tt.first.id == tt.second.id && tt.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Loaded from NS: ${tt.second.id} ")
confirmLastTempTargetsIdIfGreater(tt.second.id)
processChangedTempTargets()
return
}
// only NsId changed, no need to upload
tt.first.onlyNsIdAdded(tt.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Only NS id changed ID: ${tt.second.id} ")
confirmLastTempTargetsIdIfGreater(tt.second.id)
processChangedTempTargets()
return
}
// without nsId = create new
tt.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId")
// existing with nsId = update
tt.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastFoodIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_food_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Food data sync from $lastSynced")
sp.putLong(R.string.key_ns_food_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedFoods() {
if (isPaused) return
val lastDbId = appRepository.getLastFoodId() ?: 0L
var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_food_last_synced_id, 0)
startId = 0
}
queueCounter.foodsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food ->
aapsLogger.info(LTag.NSCLIENT, "Loading Food data Start: $startId ${food.first} forID: ${food.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
food.first.id == food.second.id && food.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Loaded from NS: ${food.second.id} ")
confirmLastFoodIdIfGreater(food.second.id)
processChangedFoods()
return
}
// only NsId changed, no need to upload
food.first.onlyNsIdAdded(food.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Only NS id changed ID: ${food.second.id} ")
confirmLastFoodIdIfGreater(food.second.id)
processChangedFoods()
return
}
// without nsId = create new
food.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId")
// with nsId = update
food.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting GlucoseValue data sync from $lastSynced")
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedGlucoseValues() {
if (isPaused) return
val lastDbId = appRepository.getLastGlucoseValueId() ?: 0L
var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, 0)
startId = 0
}
queueCounter.gvsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv ->
aapsLogger.info(LTag.NSCLIENT, "Loading GlucoseValue data Start: $startId ${gv.first} forID: ${gv.second.id} ")
if (activePlugin.activeBgSource.shouldUploadToNs(gv.first)) {
when {
// new record with existing NS id => must be coming from NS => ignore
gv.first.id == gv.second.id && gv.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Loaded from NS: ${gv.second.id} ")
confirmLastGlucoseValueIdIfGreater(gv.second.id)
processChangedGlucoseValues()
return
}
// only NsId changed, no need to upload
gv.first.onlyNsIdAdded(gv.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Only NS id changed ID: ${gv.second.id} ")
confirmLastGlucoseValueIdIfGreater(gv.second.id)
processChangedGlucoseValues()
return
}
// without nsId = create new
gv.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId")
// with nsId = update
else -> // gv.first.interfaceIDs.nightscoutId != null
activePlugin.activeNsClient?.nsUpdate("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId")
}
} else {
confirmLastGlucoseValueIdIfGreater(gv.second.id)
processChangedGlucoseValues()
return
}
}
}
override fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TherapyEvents data sync from $lastSynced")
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedTherapyEvents() {
if (isPaused) return
val lastDbId = appRepository.getLastTherapyEventId() ?: 0L
var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, 0)
startId = 0
}
queueCounter.tesRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te ->
aapsLogger.info(LTag.NSCLIENT, "Loading TherapyEvents data Start: $startId ${te.first} forID: ${te.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
te.first.id == te.second.id && te.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Loaded from NS: ${te.second.id} ")
confirmLastTherapyEventIdIfGreater(te.second.id)
processChangedTherapyEvents()
return
}
// only NsId changed, no need to upload
te.first.onlyNsIdAdded(te.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Only NS id changed ID: ${te.second.id} ")
confirmLastTherapyEventIdIfGreater(te.second.id)
processChangedTherapyEvents()
return
}
// without nsId = create new
te.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId")
// nsId = update
te.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting DeviceStatus data sync from $lastSynced")
sp.putLong(R.string.key_ns_device_status_last_synced_id, lastSynced)
}
}
override suspend fun processChangedDeviceStatuses() {
if (isPaused) return
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_device_status_last_synced_id, 0)
startId = 0
}
queueCounter.dssRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus")
when {
// without nsId = create new
deviceStatus.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, lastDbId), "$startId/$lastDbId")
// with nsId = ignore
deviceStatus.interfaceIDs.nightscoutId != null -> Any()
}
return
}
}
override fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryBasal data sync from $lastSynced")
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedTemporaryBasals() {
if (isPaused) return
val lastDbId = appRepository.getLastTemporaryBasalId() ?: 0L
var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
startId = 0
}
queueCounter.tbrsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb ->
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryBasal data Start: $startId ${tb.first} forID: ${tb.second.id} ")
val profile = profileFunction.getProfile(tb.first.timestamp)
if (profile != null) {
when {
// new record with existing NS id => must be coming from NS => ignore
tb.first.id == tb.second.id && tb.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Loaded from NS: ${tb.second.id} ")
confirmLastTemporaryBasalIdIfGreater(tb.second.id)
processChangedTemporaryBasals()
return
}
// only NsId changed, no need to upload
tb.first.onlyNsIdAdded(tb.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Only NS id changed ID: ${tb.second.id} ")
confirmLastTemporaryBasalIdIfGreater(tb.second.id)
processChangedTemporaryBasals()
return
}
// without nsId = create new
tb.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId", profile)
// with nsId = update
tb.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId", profile)
}
return
} else {
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. No profile: ${tb.second.id} ")
confirmLastTemporaryBasalIdIfGreater(tb.second.id)
processChangedTemporaryBasals()
return
}
}
}
override fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting ExtendedBolus data sync from $lastSynced")
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedExtendedBoluses() {
if (isPaused) return
val lastDbId = appRepository.getLastExtendedBolusId() ?: 0L
var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
startId = 0
}
queueCounter.ebsRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb ->
aapsLogger.info(LTag.NSCLIENT, "Loading ExtendedBolus data Start: $startId ${eb.first} forID: ${eb.second.id} ")
val profile = profileFunction.getProfile(eb.first.timestamp)
if (profile != null) {
when {
// new record with existing NS id => must be coming from NS => ignore
eb.first.id == eb.second.id && eb.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Loaded from NS: ${eb.second.id} ")
confirmLastExtendedBolusIdIfGreater(eb.second.id)
processChangedExtendedBoluses()
return
}
// only NsId changed, no need to upload
eb.first.onlyNsIdAdded(eb.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Only NS id changed ID: ${eb.second.id} ")
confirmLastExtendedBolusIdIfGreater(eb.second.id)
processChangedExtendedBoluses()
return
}
// without nsId = create new
eb.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId", profile)
// with nsId = update
eb.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId", profile)
}
return
} else {
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. No profile: ${eb.second.id} ")
confirmLastExtendedBolusIdIfGreater(eb.second.id)
processChangedExtendedBoluses()
return
}
}
}
override fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting ProfileSwitch data sync from $lastSynced")
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedProfileSwitches() {
if (isPaused) return
val lastDbId = appRepository.getLastProfileSwitchId() ?: 0L
var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, 0)
startId = 0
}
queueCounter.pssRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps ->
aapsLogger.info(LTag.NSCLIENT, "Loading ProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Loaded from NS: ${ps.second.id} ")
confirmLastProfileSwitchIdIfGreater(ps.second.id)
processChangedProfileSwitches()
return
}
// only NsId changed, no need to upload
ps.first.onlyNsIdAdded(ps.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
confirmLastProfileSwitchIdIfGreater(ps.second.id)
processChangedProfileSwitches()
return
}
// without nsId = create new
ps.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
// with nsId = update
ps.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting EffectiveProfileSwitch data sync from $lastSynced")
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedEffectiveProfileSwitches() {
if (isPaused) return
val lastDbId = appRepository.getLastEffectiveProfileSwitchId() ?: 0L
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
startId = 0
}
queueCounter.epssRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps ->
aapsLogger.info(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Loaded from NS: ${ps.second.id} ")
confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id)
processChangedEffectiveProfileSwitches()
return
}
// only NsId changed, no need to upload
ps.first.onlyNsIdAdded(ps.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id)
processChangedEffectiveProfileSwitches()
return
}
// without nsId = create new
ps.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
// with nsId = update
ps.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced")
sp.putLong(R.string.key_ns_offline_event_last_synced_id, lastSynced)
}
}
override tailrec suspend fun processChangedOfflineEvents() {
if (isPaused) return
val lastDbId = appRepository.getLastOfflineEventId() ?: 0L
var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
if (startId > lastDbId) {
sp.putLong(R.string.key_ns_offline_event_last_synced_id, 0)
startId = 0
}
queueCounter.oesRemaining = lastDbId - startId
rxBus.send(EventNSClientUpdateGuiQueue())
appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe ->
aapsLogger.info(LTag.NSCLIENT, "Loading OfflineEvent data Start: $startId ${oe.first} forID: ${oe.second.id} ")
when {
// new record with existing NS id => must be coming from NS => ignore
oe.first.id == oe.second.id && oe.first.interfaceIDs.nightscoutId != null -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Loaded from NS: ${oe.second.id} ")
confirmLastOfflineEventIdIfGreater(oe.second.id)
processChangedOfflineEvents()
return
}
// only NsId changed, no need to upload
oe.first.onlyNsIdAdded(oe.second) -> {
aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Only NS id changed ID: ${oe.second.id} ")
confirmLastOfflineEventIdIfGreater(oe.second.id)
processChangedOfflineEvents()
return
}
// without nsId = create new
oe.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId")
// existing with nsId = update
oe.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId")
}
return
}
}
override fun confirmLastProfileStore(lastSynced: Long) {
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
}
override suspend fun processChangedProfileStore() {
if (isPaused) return
val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0)
val lastChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
if (lastChange == 0L) return
if (lastChange > lastSync) {
if (activePlugin.activeProfileSource.profile?.allProfilesValid != true) return
val profileStore = activePlugin.activeProfileSource.profile
val profileJson = profileStore?.data ?: return
// add for v3
if (JsonHelper.safeGetLongAllowNull(profileJson, "date") == null)
profileJson.put("date", profileStore.getStartDate())
activePlugin.activeNsClient?.nsAdd("profile", DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
}
}
}

View file

@ -5,7 +5,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
import android.os.IBinder import android.os.IBinder
import android.provider.ContactsContract
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreference import androidx.preference.SwitchPreference
@ -24,7 +23,6 @@ import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.source.DoingOwnUploadSource import info.nightscout.interfaces.source.DoingOwnUploadSource
import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.DataSyncSelectorV1
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.sync.Sync
import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.R

View file

@ -25,7 +25,6 @@ import info.nightscout.interfaces.notifications.Notification
import info.nightscout.interfaces.nsclient.NSAlarm import info.nightscout.interfaces.nsclient.NSAlarm
import info.nightscout.interfaces.nsclient.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.sync.DataSyncSelectorV1
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.JsonHelper.safeGetString import info.nightscout.interfaces.utils.JsonHelper.safeGetString
import info.nightscout.interfaces.utils.JsonHelper.safeGetStringAllowNull import info.nightscout.interfaces.utils.JsonHelper.safeGetStringAllowNull
@ -34,6 +33,7 @@ import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
import info.nightscout.plugins.sync.nsclient.DataSyncSelectorV1
import info.nightscout.plugins.sync.nsclient.NSClientPlugin import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck
@ -179,6 +179,18 @@ import javax.inject.Inject
.toObservable(EventNewHistoryData::class.java) .toObservable(EventNewHistoryData::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe({ resend("NEW_DATA") }, fabricPrivacy::logException) .subscribe({ resend("NEW_DATA") }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventDeviceStatusChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ resend("EventDeviceStatusChange") }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventTherapyEventChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ resend("EventTherapyEventChange") }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventOfflineChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ resend("EventOfflineChange") }, fabricPrivacy::logException)
} }
override fun onDestroy() { override fun onDestroy() {
@ -541,6 +553,7 @@ import javax.inject.Inject
} }
} }
rxBus.send(EventNSClientNewLog("◄ LAST", dateUtil.dateAndTimeString(latestDateInReceivedData))) rxBus.send(EventNSClientNewLog("◄ LAST", dateUtil.dateAndTimeString(latestDateInReceivedData)))
resend("LAST")
} catch (e: JSONException) { } catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e) aapsLogger.error("Unhandled exception", e)
} }
@ -551,7 +564,7 @@ import javax.inject.Inject
} }
} }
fun dbUpdate(collection: String, _id: String?, data: JSONObject?, originalObject: Any, progress: String) { fun dbUpdate(collection: String, @Suppress("LocalVariableName") _id: String?, data: JSONObject?, originalObject: Any, progress: String) {
try { try {
if (_id == null) return if (_id == null) return
if (!isConnected || !hasWriteAuth) return if (!isConnected || !hasWriteAuth) return
@ -595,10 +608,10 @@ import javax.inject.Inject
if (!isConnected || !hasWriteAuth) return@runBlocking if (!isConnected || !hasWriteAuth) return@runBlocking
scope.async { scope.async {
if (socket?.connected() != true) return@async if (socket?.connected() != true) return@async
if (lastAckTime > System.currentTimeMillis() - 10 * 1000L) { // if (lastAckTime > System.currentTimeMillis() - 10 * 1000L) {
aapsLogger.debug(LTag.NSCLIENT, "Skipping resend by lastAckTime: " + (System.currentTimeMillis() - lastAckTime) / 1000L + " sec") // aapsLogger.debug(LTag.NSCLIENT, "Skipping resend by lastAckTime: " + (System.currentTimeMillis() - lastAckTime) / 1000L + " sec")
return@async // return@async
} // }
rxBus.send(EventNSClientNewLog("● QUEUE", "Resend started: $reason")) rxBus.send(EventNSClientNewLog("● QUEUE", "Resend started: $reason"))
dataSyncSelectorV1.doUpload() dataSyncSelectorV1.doUpload()
rxBus.send(EventNSClientNewLog("● QUEUE", "Resend ended: $reason")) rxBus.send(EventNSClientNewLog("● QUEUE", "Resend ended: $reason"))

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.os.SystemClock import android.os.SystemClock
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import androidx.work.workDataOf import androidx.work.workDataOf
import info.nightscout.core.utils.notify
import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
@ -22,7 +23,6 @@ import info.nightscout.interfaces.sync.DataSyncSelector.PairProfileSwitch
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget
import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent
import info.nightscout.interfaces.sync.DataSyncSelectorV1
import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
@ -40,7 +40,6 @@ class NSClientAddAckWorker(
@Inject lateinit var dataWorkerStorage: DataWorkerStorage @Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
@Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var storeDataForDb: StoreDataForDb @Inject lateinit var storeDataForDb: StoreDataForDb
@ -60,152 +59,128 @@ class NSClientAddAckWorker(
is PairTemporaryTarget -> { is PairTemporaryTarget -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdTemporaryTargets.add(pair.value) storeDataForDb.nsIdTemporaryTargets.add(pair.value)
dataSyncSelectorV1.confirmLastTempTargetsIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedTempTargets()
} }
is PairGlucoseValue -> { is PairGlucoseValue -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdGlucoseValues.add(pair.value) storeDataForDb.nsIdGlucoseValues.add(pair.value)
dataSyncSelectorV1.confirmLastGlucoseValueIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedGlucoseValues()
} }
is PairFood -> { is PairFood -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdFoods.add(pair.value) storeDataForDb.nsIdFoods.add(pair.value)
dataSyncSelectorV1.confirmLastFoodIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting // Send new if waiting
dataSyncSelectorV1.processChangedFoods()
} }
is PairTherapyEvent -> { is PairTherapyEvent -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdTherapyEvents.add(pair.value) storeDataForDb.nsIdTherapyEvents.add(pair.value)
dataSyncSelectorV1.confirmLastTherapyEventIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedTherapyEvents()
} }
is PairBolus -> { is PairBolus -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdBoluses.add(pair.value) storeDataForDb.nsIdBoluses.add(pair.value)
dataSyncSelectorV1.confirmLastBolusIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedBoluses()
} }
is PairCarbs -> { is PairCarbs -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdCarbs.add(pair.value) storeDataForDb.nsIdCarbs.add(pair.value)
dataSyncSelectorV1.confirmLastCarbsIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedCarbs()
} }
is PairBolusCalculatorResult -> { is PairBolusCalculatorResult -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
storeDataForDb.nsIdBolusCalculatorResults.add(pair.value) storeDataForDb.nsIdBolusCalculatorResults.add(pair.value)
dataSyncSelectorV1.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedBolusCalculatorResults()
} }
is PairTemporaryBasal -> { is PairTemporaryBasal -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdTemporaryBasals.add(pair.value) storeDataForDb.nsIdTemporaryBasals.add(pair.value)
dataSyncSelectorV1.confirmLastTemporaryBasalIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedTemporaryBasals()
} }
is PairExtendedBolus -> { is PairExtendedBolus -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdExtendedBoluses.add(pair.value) storeDataForDb.nsIdExtendedBoluses.add(pair.value)
dataSyncSelectorV1.confirmLastExtendedBolusIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedExtendedBoluses()
} }
is PairProfileSwitch -> { is PairProfileSwitch -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdProfileSwitches.add(pair.value) storeDataForDb.nsIdProfileSwitches.add(pair.value)
dataSyncSelectorV1.confirmLastProfileSwitchIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedProfileSwitches()
} }
is PairEffectiveProfileSwitch -> { is PairEffectiveProfileSwitch -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdEffectiveProfileSwitches.add(pair.value) storeDataForDb.nsIdEffectiveProfileSwitches.add(pair.value)
dataSyncSelectorV1.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedEffectiveProfileSwitches()
} }
is DataSyncSelector.PairDeviceStatus -> { is DataSyncSelector.PairDeviceStatus -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdDeviceStatuses.add(pair.value) storeDataForDb.nsIdDeviceStatuses.add(pair.value)
dataSyncSelectorV1.confirmLastDeviceStatusIdIfGreater(pair.value.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked DeviceStatus " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked DeviceStatus " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedDeviceStatuses()
} }
is PairProfileStore -> { is PairProfileStore -> {
dataSyncSelectorV1.confirmLastProfileStore(ack.originalObject.id) val pair = ack.originalObject
pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileStore " + ack.id)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileStore " + ack.id))
} }
is PairOfflineEvent -> { is PairOfflineEvent -> {
val pair = ack.originalObject val pair = ack.originalObject
pair.value.interfaceIDs.nightscoutId = ack.id pair.value.interfaceIDs.nightscoutId = ack.id
pair.confirmed = true
storeDataForDb.nsIdOfflineEvents.add(pair.value) storeDataForDb.nsIdOfflineEvents.add(pair.value)
dataSyncSelectorV1.confirmLastOfflineEventIdIfGreater(pair.id)
storeDataForDb.scheduleNsIdUpdate() storeDataForDb.scheduleNsIdUpdate()
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId)) rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId))
// Send new if waiting
dataSyncSelectorV1.processChangedOfflineEvents()
} }
} }
ack.originalObject?.let { synchronized(it) { it.notify() } }
return ret return ret
} }
} }

View file

@ -3,6 +3,7 @@ package info.nightscout.plugins.sync.nsclient.workers
import android.content.Context import android.content.Context
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import androidx.work.workDataOf import androidx.work.workDataOf
import info.nightscout.core.utils.notify
import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
@ -18,7 +19,6 @@ import info.nightscout.interfaces.sync.DataSyncSelector.PairProfileSwitch
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget
import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent
import info.nightscout.interfaces.sync.DataSyncSelectorV1
import info.nightscout.plugins.sync.nsclient.acks.NSUpdateAck import info.nightscout.plugins.sync.nsclient.acks.NSUpdateAck
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -34,7 +34,6 @@ class NSClientUpdateRemoveAckWorker(
@Inject lateinit var dataWorkerStorage: DataWorkerStorage @Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
@Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var aapsSchedulers: AapsSchedulers
override suspend fun doWorkAndLog(): Result { override suspend fun doWorkAndLog(): Result {
@ -47,112 +46,89 @@ class NSClientUpdateRemoveAckWorker(
when (ack.originalObject) { when (ack.originalObject) {
is PairTemporaryTarget -> { is PairTemporaryTarget -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastTempTargetsIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryTarget" + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryTarget" + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedTempTargets()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairGlucoseValue -> { is PairGlucoseValue -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastGlucoseValueIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked GlucoseValue " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked GlucoseValue " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedGlucoseValues()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairFood -> { is PairFood -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastFoodIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Food " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Food " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedFoods()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairTherapyEvent -> { is PairTherapyEvent -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastTherapyEventIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TherapyEvent " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TherapyEvent " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedTherapyEvents()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairBolus -> { is PairBolus -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastBolusIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Bolus " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Bolus " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedBoluses()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairCarbs -> { is PairCarbs -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastCarbsIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Carbs " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Carbs " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedCarbs()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairBolusCalculatorResult -> { is PairBolusCalculatorResult -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastBolusCalculatorResultsIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked BolusCalculatorResult " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked BolusCalculatorResult " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedBolusCalculatorResults()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairTemporaryBasal -> { is PairTemporaryBasal -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastTemporaryBasalIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryBasal " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryBasal " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedTemporaryBasals()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairExtendedBolus -> { is PairExtendedBolus -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastExtendedBolusIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ExtendedBolus " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ExtendedBolus " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedExtendedBoluses()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairProfileSwitch -> { is PairProfileSwitch -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastProfileSwitchIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ProfileSwitch " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ProfileSwitch " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedProfileSwitches()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairEffectiveProfileSwitch -> { is PairEffectiveProfileSwitch -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedEffectiveProfileSwitches()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
is PairOfflineEvent -> { is PairOfflineEvent -> {
val pair = ack.originalObject val pair = ack.originalObject
dataSyncSelectorV1.confirmLastOfflineEventIdIfGreater(pair.id) pair.confirmed = true
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked OfflineEvent" + ack._id)) rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked OfflineEvent" + ack._id))
// Send new if waiting
dataSyncSelectorV1.processChangedOfflineEvents()
ret = Result.success(workDataOf("ProcessedData" to pair.toString())) ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
} }
} }
ack.originalObject?.let { synchronized(it) { it.notify() } }
return ret return ret
} }
} }

View file

@ -7,7 +7,6 @@ import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.DataSyncSelectorV3
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
@ -22,7 +21,7 @@ import javax.inject.Singleton
@OpenForTesting @OpenForTesting
@Singleton @Singleton
class DataSyncSelectorV3Impl @Inject constructor( class DataSyncSelectorV3 @Inject constructor(
private val sp: SP, private val sp: SP,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
@ -32,7 +31,7 @@ class DataSyncSelectorV3Impl @Inject constructor(
private val rxBus: RxBus, private val rxBus: RxBus,
private val storeDataForDb: StoreDataForDb, private val storeDataForDb: StoreDataForDb,
private val config: Config private val config: Config
) : DataSyncSelectorV3 { ) : DataSyncSelector {
class QueueCounter( class QueueCounter(
var bolusesRemaining: Long = -1L, var bolusesRemaining: Long = -1L,
@ -127,14 +126,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
else sp.remove(R.string.key_ns_device_status_last_synced_id) else sp.remove(R.string.key_ns_device_status_last_synced_id)
} }
fun confirmLastBolusIdIfGreater(lastSynced: Long) { private fun confirmLastBolusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Bolus data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting Bolus data sync from $lastSynced")
sp.putLong(R.string.key_ns_bolus_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_bolus_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedBoluses() { private suspend fun processChangedBoluses() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -170,14 +169,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastCarbsIdIfGreater(lastSynced: Long) { private fun confirmLastCarbsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Carbs data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting Carbs data sync from $lastSynced")
sp.putLong(R.string.key_ns_carbs_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_carbs_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedCarbs() { private suspend fun processChangedCarbs() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -213,14 +212,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) { private fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting BolusCalculatorResult data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting BolusCalculatorResult data sync from $lastSynced")
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedBolusCalculatorResults() { private suspend fun processChangedBolusCalculatorResults() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -264,14 +263,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) { private fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryTarget data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryTarget data sync from $lastSynced")
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_temporary_target_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedTempTargets() { private suspend fun processChangedTempTargets() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -307,14 +306,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastFoodIdIfGreater(lastSynced: Long) { private fun confirmLastFoodIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_food_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_food_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting Food data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting Food data sync from $lastSynced")
sp.putLong(R.string.key_ns_food_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_food_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedFoods() { private suspend fun processChangedFoods() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -350,14 +349,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) { private fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting GlucoseValue data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting GlucoseValue data sync from $lastSynced")
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_glucose_value_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedGlucoseValues() { private suspend fun processChangedGlucoseValues() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -395,14 +394,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) { private fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TherapyEvents data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting TherapyEvents data sync from $lastSynced")
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_therapy_event_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedTherapyEvents() { private suspend fun processChangedTherapyEvents() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -438,44 +437,45 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) { private fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting DeviceStatus data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting DeviceStatus data sync from $lastSynced")
sp.putLong(R.string.key_ns_device_status_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedDeviceStatuses() { private suspend fun processChangedDeviceStatuses() {
if (isPaused) return var cont = true
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L while (cont) {
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0) if (isPaused) return
if (startId > lastDbId) { val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId") var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
sp.putLong(R.string.key_ns_device_status_last_synced_id, 0) if (startId > lastDbId) {
startId = 0 aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
} sp.putLong(R.string.key_ns_device_status_last_synced_id, 0)
queueCounter.dssRemaining = lastDbId - startId startId = 0
rxBus.send(EventNSClientUpdateGuiQueue()) }
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus -> queueCounter.dssRemaining = lastDbId - startId
//aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus") rxBus.send(EventNSClientUpdateGuiQueue())
// without nsId = create new appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
if (deviceStatus.interfaceIDs.nightscoutId == null) { //aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus")
if (activePlugin.activeNsClient?.nsAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, lastDbId), "$startId/$lastDbId") == true) cont = activePlugin.activeNsClient?.nsAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, lastDbId), "$startId/$lastDbId") ?: false
confirmLastDeviceStatusIdIfGreater(lastDbId) if (cont) confirmLastDeviceStatusIdIfGreater(deviceStatus.id)
// with nsId = ignore
} ?: run {
cont = false
} }
// with nsId = ignore
} }
queueCounter.dssRemaining = 0
} }
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) { private fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryBasal data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryBasal data sync from $lastSynced")
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedTemporaryBasals() { private suspend fun processChangedTemporaryBasals() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -512,14 +512,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) { private fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting ExtendedBolus data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting ExtendedBolus data sync from $lastSynced")
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedExtendedBoluses() { private suspend fun processChangedExtendedBoluses() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -558,14 +558,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) { private fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting ProfileSwitch data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting ProfileSwitch data sync from $lastSynced")
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_profile_switch_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedProfileSwitches() { private suspend fun processChangedProfileSwitches() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -601,14 +601,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) { private fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting EffectiveProfileSwitch data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting EffectiveProfileSwitch data sync from $lastSynced")
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedEffectiveProfileSwitches() { private suspend fun processChangedEffectiveProfileSwitches() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -644,14 +644,14 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) { private fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) { if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) {
//aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced") //aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced")
sp.putLong(R.string.key_ns_offline_event_last_synced_id, lastSynced) sp.putLong(R.string.key_ns_offline_event_last_synced_id, lastSynced)
} }
} }
suspend fun processChangedOfflineEvents() { private suspend fun processChangedOfflineEvents() {
var cont = true var cont = true
while (cont) { while (cont) {
if (isPaused) return if (isPaused) return
@ -687,11 +687,11 @@ class DataSyncSelectorV3Impl @Inject constructor(
} }
} }
fun confirmLastProfileStore(lastSynced: Long) { private fun confirmLastProfileStore(lastSynced: Long) {
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced) sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
} }
suspend fun processChangedProfileStore() { private suspend fun processChangedProfileStore() {
if (isPaused) return if (isPaused) return
val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0) val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0)
val lastChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0) val lastChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)

View file

@ -30,7 +30,6 @@ import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.Profile import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.source.NSClientSource import info.nightscout.interfaces.source.NSClientSource
import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.DataSyncSelectorV3
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.sync.Sync
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
@ -66,11 +65,14 @@ import info.nightscout.plugins.sync.nsclientV3.workers.LoadTreatmentsWorker
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventAppExit import info.nightscout.rx.events.EventAppExit
import info.nightscout.rx.events.EventDeviceStatusChange
import info.nightscout.rx.events.EventDismissNotification import info.nightscout.rx.events.EventDismissNotification
import info.nightscout.rx.events.EventNSClientNewLog import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.rx.events.EventNewHistoryData import info.nightscout.rx.events.EventNewHistoryData
import info.nightscout.rx.events.EventOfflineChange
import info.nightscout.rx.events.EventPreferenceChange import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventSWSyncStatus import info.nightscout.rx.events.EventSWSyncStatus
import info.nightscout.rx.events.EventTherapyEventChange
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.sdk.NSAndroidClientImpl import info.nightscout.sdk.NSAndroidClientImpl
@ -224,6 +226,18 @@ class NSClientV3Plugin @Inject constructor(
.toObservable(EventNewHistoryData::class.java) .toObservable(EventNewHistoryData::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe({ executeUpload("NEW_DATA", forceNew = false) }, fabricPrivacy::logException) .subscribe({ executeUpload("NEW_DATA", forceNew = false) }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventDeviceStatusChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ executeUpload("EventDeviceStatusChange", forceNew = false) }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventTherapyEventChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ executeUpload("EventTherapyEventChange", forceNew = false) }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventOfflineChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ executeUpload("EventOfflineChange", forceNew = false) }, fabricPrivacy::logException)
runLoop = Runnable { runLoop = Runnable {
var refreshInterval = T.mins(5).msecs() var refreshInterval = T.mins(5).msecs()

View file

@ -5,7 +5,7 @@ import androidx.work.WorkerParameters
import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.sync.DataSyncSelectorV3 import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog import info.nightscout.rx.events.EventNSClientNewLog

View file

@ -45,7 +45,7 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
@Mock lateinit var receiverDelegate: ReceiverDelegate @Mock lateinit var receiverDelegate: ReceiverDelegate
@Mock lateinit var uiInteraction: UiInteraction @Mock lateinit var uiInteraction: UiInteraction
@Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3Impl @Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3
@Mock lateinit var nsAndroidClient: NSAndroidClient @Mock lateinit var nsAndroidClient: NSAndroidClient
@Mock lateinit var uel: UserEntryLogger @Mock lateinit var uel: UserEntryLogger
@Mock lateinit var nsClientSource: NSClientSource @Mock lateinit var nsClientSource: NSClientSource

View file

@ -8,7 +8,7 @@ import info.nightscout.androidaps.TestBase
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3Impl import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -24,7 +24,7 @@ import org.mockito.Mockito.`when`
internal class DataSyncWorkerTest : TestBase() { internal class DataSyncWorkerTest : TestBase() {
@Mock lateinit var fabricPrivacy: FabricPrivacy @Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3Impl @Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3
@Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var nsClient: NsClient @Mock lateinit var nsClient: NsClient
@Mock lateinit var rxBus: RxBus @Mock lateinit var rxBus: RxBus

View file

@ -17,11 +17,11 @@ import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.receivers.ReceiverStatusStore import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.source.NSClientSource import info.nightscout.interfaces.source.NSClientSource
import info.nightscout.interfaces.sync.DataSyncSelectorV3
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3 import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus