improve BG sync

This commit is contained in:
Milos Kozak 2021-02-08 13:40:09 +01:00
parent 887819edf4
commit 145765e611
12 changed files with 68 additions and 29 deletions

View file

@ -18,12 +18,15 @@ import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.directionToIcon
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.valueToUnitsString
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.util.concurrent.TimeUnit
@ -89,8 +92,8 @@ class BGSourceFragment : DaggerFragment() {
@Synchronized
override fun onDestroyView() {
super.onDestroyView()
_binding = null
binding.recyclerview.adapter = null // avoid leaks
_binding = null
}
inner class RecyclerViewAdapter internal constructor(private var glucoseValues: List<GlucoseValue>) : RecyclerView.Adapter<RecyclerViewAdapter.GlucoseValuesViewHolder>() {

View file

@ -132,14 +132,19 @@ class DexcomPlugin @Inject constructor(
} else {
null
}
dexcomPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, calibrations, sensorStartTime)).subscribe({ savedValues ->
savedValues.forEach {
dexcomPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, calibrations, sensorStartTime)).subscribe({ result ->
result.inserted.forEach {
broadcastToXDrip(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
if (it.interfaceIDs.nightscoutId != null)
nsUpload.updateBg(it, sourceSensor.text)
else
nsUpload.uploadBg(it, sourceSensor.text)
nsUpload.uploadBg(it, sourceSensor.text)
//aapsLogger.debug("XXXXX: dbAdd $it")
}
}
result.updated.forEach {
broadcastToXDrip(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.updateBg(it, sourceSensor.text)
//aapsLogger.debug("XXXXX: dpUpdate $it")
}
}
}, {

View file

@ -118,7 +118,7 @@ class EversensePlugin @Inject constructor(
sourceSensor = GlucoseValue.SourceSensor.EVERSENSE
)
eversensePlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
savedValues.inserted.forEach {
broadcastToXDrip(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.EVERSENSE.text)

View file

@ -76,7 +76,7 @@ class GlimpPlugin @Inject constructor(
sourceSensor = GlucoseValue.SourceSensor.GLIMP
)
glimpPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
savedValues.inserted.forEach {
broadcastToXDrip(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.GLIMP.text)

View file

@ -94,7 +94,7 @@ class MM640gPlugin @Inject constructor(
}
}
mM640gPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
savedValues.all().forEach {
broadcastToXDrip(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.MM_600_SERIES.text)

View file

@ -127,13 +127,19 @@ class NSClientSourcePlugin @Inject constructor(
for (i in 0 until jsonArray.length())
glucoseValues += toGv(jsonArray.getJSONObject(i))
}
nsClientSourcePlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
nsClientSourcePlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null, !nsClientSourcePlugin.isEnabled())).subscribe({ result ->
result.updated.forEach {
//aapsLogger.debug("XXXXX: Updated $it")
broadcastToXDrip(it)
nsClientSourcePlugin.detectSource(it)
}
result.inserted.forEach {
//aapsLogger.debug("XXXXX: Inserted $it")
broadcastToXDrip(it)
nsClientSourcePlugin.detectSource(it)
}
}, {
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Eversense App", it)
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from NSClient App", it)
})
} catch (e: Exception) {
aapsLogger.error("Unhandled exception", e)

View file

@ -87,7 +87,7 @@ class PoctechPlugin @Inject constructor(
)
}
poctechPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
savedValues.inserted.forEach {
broadcastToXDrip(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.POCTECH_NATIVE.text)

View file

@ -108,7 +108,7 @@ class RandomBgPlugin @Inject constructor(
sourceSensor = GlucoseValue.SourceSensor.RANDOM
)
disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
savedValues.inserted.forEach {
xDripBroadcast(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.RANDOM.text)

View file

@ -76,7 +76,7 @@ class TomatoPlugin @Inject constructor(
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_TOMATO
)
tomatoPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
savedValues.inserted.forEach {
broadcastToXDrip(it)
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.LIBRE_1_TOMATO.text)

View file

@ -86,7 +86,7 @@ class XdripPlugin @Inject constructor(
?: "")
)
xdripPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
savedValues.forEach {
savedValues.all().forEach {
xdripPlugin.detectSource(it)
}
}, {

View file

@ -40,8 +40,7 @@ data class GlucoseValue(
trendArrow == other.trendArrow &&
noise == other.noise &&
sourceSensor == other.sourceSensor &&
isValid == other.isValid &&
interfaceIDs.nightscoutId == other.interfaceIDs.nightscoutId
isValid == other.isValid
fun isRecordDeleted(other: GlucoseValue): Boolean =
isValid && !other.isValid

View file

@ -9,11 +9,14 @@ import info.nightscout.androidaps.database.entities.TherapyEvent
class CgmSourceTransaction(
private val glucoseValues: List<TransactionGlucoseValue>,
private val calibrations: List<Calibration>,
private val sensorInsertionTime: Long?
) : Transaction<List<GlucoseValue>>() {
private val sensorInsertionTime: Long?,
private val syncer: Boolean = false // caller is not native source ie. NS
// syncer is allowed create records
// update synchronization ID
) : Transaction<CgmSourceTransaction.TransactionResult>() {
override fun run(): List<GlucoseValue> {
val insertedGlucoseValues = mutableListOf<GlucoseValue>()
override fun run(): TransactionResult {
val result = TransactionResult()
glucoseValues.forEach {
val current = database.glucoseValueDao.findByTimestampAndSensor(it.timestamp, it.sourceSensor)
val glucoseValue = GlucoseValue(
@ -25,15 +28,26 @@ class CgmSourceTransaction(
sourceSensor = it.sourceSensor
)
glucoseValue.interfaceIDs.nightscoutId = it.nightscoutId
// if nsId is not provided in new record, copy from current if exists
if (glucoseValue.interfaceIDs.nightscoutId == null)
current?.let { existing -> glucoseValue.interfaceIDs.nightscoutId = existing.interfaceIDs.nightscoutId }
when {
current == null -> {
// new record, create new
current == null -> {
database.glucoseValueDao.insertNewEntry(glucoseValue)
insertedGlucoseValues.add(glucoseValue)
result.inserted.add(glucoseValue)
}
!current.contentEqualsTo(glucoseValue) -> {
// different record, update
!current.contentEqualsTo(glucoseValue) && !syncer -> {
glucoseValue.id = current.id
database.glucoseValueDao.updateExistingEntry(glucoseValue)
result.updated.add(glucoseValue)
}
// update NS id if didn't exist and now provided
current.interfaceIDs.nightscoutId == null && it.nightscoutId != null && syncer -> {
glucoseValue.id = current.id
database.glucoseValueDao.updateExistingEntry(glucoseValue)
result.updated.add(glucoseValue)
}
}
}
@ -54,7 +68,7 @@ class CgmSourceTransaction(
))
}
}
return insertedGlucoseValues
return result
}
data class TransactionGlucoseValue(
@ -71,4 +85,16 @@ class CgmSourceTransaction(
val timestamp: Long,
val value: Double
)
class TransactionResult {
val inserted = mutableListOf<GlucoseValue>()
val updated = mutableListOf<GlucoseValue>()
fun all(): MutableList<GlucoseValue> =
mutableListOf<GlucoseValue>().also { result ->
result.addAll(inserted)
result.addAll(updated)
}
}
}