From 25c048640d1f7d0721cb05f4b66e5caea17d1894 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 9 Nov 2021 15:26:09 +0100 Subject: [PATCH 1/7] Glunovo plugin --- .../activities/MyPreferenceFragment.kt | 3 + .../dependencyInjection/PluginsModule.kt | 6 + .../plugins/source/BGSourceFragment.kt | 1 + .../plugins/source/GlunovoPlugin.kt | 125 ++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + .../userEntry/UserEntryPresentationHelper.kt | 1 + core/src/main/res/drawable/ic_glunovo.xml | 85 ++++++++++++ .../database/entities/GlucoseValue.kt | 1 + .../androidaps/database/entities/UserEntry.kt | 1 + 9 files changed, 225 insertions(+) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt create mode 100644 core/src/main/res/drawable/ic_glunovo.xml diff --git a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt index 143919db87..b9cd7b9d0a 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt @@ -48,6 +48,7 @@ import info.nightscout.androidaps.plugins.source.EversensePlugin import info.nightscout.androidaps.plugins.source.GlimpPlugin import info.nightscout.androidaps.plugins.source.PoctechPlugin import info.nightscout.androidaps.plugins.source.TomatoPlugin +import info.nightscout.androidaps.plugins.source.GlunovoPlugin import info.nightscout.androidaps.utils.SafeParse import info.nightscout.androidaps.utils.alertDialogs.OKDialog.show import info.nightscout.androidaps.utils.protection.PasswordCheck @@ -90,6 +91,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang @Inject lateinit var glimpPlugin: GlimpPlugin @Inject lateinit var poctechPlugin: PoctechPlugin @Inject lateinit var tomatoPlugin: TomatoPlugin + @Inject lateinit var glunovoPlugin: GlunovoPlugin @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin @Inject lateinit var statusLinePlugin: StatusLinePlugin @Inject lateinit var tidepoolPlugin: TidepoolPlugin @@ -160,6 +162,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang addPreferencesFromResourceIfEnabled(eversensePlugin, rootKey) addPreferencesFromResourceIfEnabled(dexcomPlugin, rootKey) addPreferencesFromResourceIfEnabled(tomatoPlugin, rootKey) + addPreferencesFromResourceIfEnabled(glunovoPlugin, rootKey) addPreferencesFromResourceIfEnabled(poctechPlugin, rootKey) addPreferencesFromResourceIfEnabled(glimpPlugin, rootKey) addPreferencesFromResourceIfEnabled(loopPlugin, rootKey, config.APS) diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt index 2a14115056..6d58752f2b 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt @@ -353,6 +353,12 @@ abstract class PluginsModule { @AllConfigs @IntoMap @IntKey(470) + abstract fun bindGlunovoPlugin(plugin: GlunovoPlugin): PluginBase + + @Binds + @AllConfigs + @IntoMap + @IntKey(475) abstract fun bindRandomBgPlugin(plugin: RandomBgPlugin): PluginBase // @Binds diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt index 48b3dbc80e..c942bf413d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt @@ -140,6 +140,7 @@ class BGSourceFragment : DaggerFragment() { R.string.nsclientbg -> Sources.NSClientSource R.string.poctech -> Sources.PocTech R.string.tomato -> Sources.Tomato + R.string.glunovo -> Sources.Glunovo R.string.xdrip -> Sources.Xdrip else -> Sources.Unknown } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt new file mode 100644 index 0000000000..ed5ebc609d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -0,0 +1,125 @@ +package info.nightscout.androidaps.plugins.source + +import android.content.Context +import android.net.Uri +import android.os.Handler +import android.os.HandlerThread +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.R +import info.nightscout.androidaps.database.AppRepository +import info.nightscout.androidaps.database.entities.GlucoseValue +import info.nightscout.androidaps.database.transactions.CgmSourceTransaction +import info.nightscout.androidaps.interfaces.BgSource +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginDescription +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.utils.XDripBroadcast +import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.androidaps.utils.sharedPreferences.SP +import io.reactivex.disposables.CompositeDisposable +import java.util.* +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GlunovoPlugin @Inject constructor( + injector: HasAndroidInjector, + resourceHelper: ResourceHelper, + aapsLogger: AAPSLogger, + private val sp: SP, + private val context: Context, + private val repository: AppRepository, + private val broadcastToXDrip: XDripBroadcast +) : PluginBase( + PluginDescription() + .mainType(PluginType.BGSOURCE) + .fragmentClass(BGSourceFragment::class.java.name) + .pluginIcon(R.drawable.ic_glunovo) + .pluginName(R.string.glunovo) + .preferencesId(R.xml.pref_bgsource) + .shortName(R.string.glunovo) + .description(R.string.description_source_glunovo), + aapsLogger, resourceHelper, injector +), BgSource { + + private val loopHandler: Handler = Handler(HandlerThread(this::class.java.simpleName + "Handler").also { it.start() }.looper) + private lateinit var refreshLoop: Runnable + + private val contentUri: Uri = Uri.parse("content://$AUTHORITY/$TABLE_NAME") + + init { + refreshLoop = Runnable { + loopHandler.postDelayed(refreshLoop, INTERVAL) + handleNewData() + } + } + + private val disposable = CompositeDisposable() + + override fun onStart() { + super.onStart() + loopHandler.postDelayed(refreshLoop, INTERVAL) + } + + override fun onStop() { + super.onStop() + loopHandler.removeCallbacks(refreshLoop) + disposable.clear() + } + + private fun handleNewData() { + if (!isEnabled()) return + + context.contentResolver.query(contentUri, null, null, null, null)?.let { cr -> + cr.moveToLast() + val curTime = Calendar.getInstance().timeInMillis + val time = cr.getLong(0) + val value = cr.getDouble(1) //value in mmol/l... + if (time > curTime || time == 0L) { + aapsLogger.error(LTag.BGSOURCE, "Error in received data date/time $time") + return + } + + if (value < 2 || value > 25) { + aapsLogger.error(LTag.BGSOURCE, "Error in received data value (value out of bounds) $value") + return + } + + val glucoseValues = mutableListOf() + glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( + timestamp = time, + value = value, + raw = 0.0, + noise = null, + trendArrow = GlucoseValue.TrendArrow.NONE, + sourceSensor = GlucoseValue.SourceSensor.GLUNOVO_NATIVE + ) + repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)) + .doOnError { + aapsLogger.error(LTag.DATABASE, "Error while saving values from Glunovo App", it) + } + .blockingGet() + .also { savedValues -> + savedValues.inserted.forEach { + broadcastToXDrip(it) + aapsLogger.debug(LTag.DATABASE, "Inserted bg $it") + } + } + + cr.close() + } + } + + override fun shouldUploadToNs(glucoseValue: GlucoseValue): Boolean = + glucoseValue.sourceSensor == GlucoseValue.SourceSensor.GLUNOVO_NATIVE && sp.getBoolean(R.string.key_dexcomg5_nsupload, false) + + companion object { + + @Suppress("SpellCheckingInspection") + const val AUTHORITY = "alexpr.co.uk.infinivocgm.cgm_db.CgmExternalProvider/" + const val TABLE_NAME = "CgmReading" + const val INTERVAL = 180000L // 3 min + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4d24ca2e1d..f776a6b2de 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -807,6 +807,8 @@ Time elapsed Poctech Receive BG values from Poctech app + Glunovo + Receive values from Glunovo app Receive BG values from Tomato app (MiaoMiao device) high_temptarget_raises_sensitivity low_temptarget_lowers_sensitivity diff --git a/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt b/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt index 2472ef84b8..615a0be902 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt @@ -70,6 +70,7 @@ class UserEntryPresentationHelper @Inject constructor( Sources.NSClientSource -> R.drawable.ic_nsclient_bg Sources.PocTech -> R.drawable.ic_poctech Sources.Tomato -> R.drawable.ic_sensor + Sources.Glunovo -> R.drawable.ic_glunovo Sources.Xdrip -> R.drawable.ic_blooddrop_48 Sources.LocalProfile -> R.drawable.ic_local_profile Sources.Loop -> R.drawable.ic_loop_closed_white diff --git a/core/src/main/res/drawable/ic_glunovo.xml b/core/src/main/res/drawable/ic_glunovo.xml new file mode 100644 index 0000000000..6fe7de817b --- /dev/null +++ b/core/src/main/res/drawable/ic_glunovo.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt index a292557866..241485a254 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt @@ -108,6 +108,7 @@ data class GlucoseValue( GLIMP("Glimp"), LIBRE_2_NATIVE("Libre2"), POCTECH_NATIVE("Poctech"), + GLUNOVO_NATIVE("Glunovo"), MM_600_SERIES("MM600Series"), EVERSENSE("Eversense"), RANDOM("Random"), diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt index 889f365ec4..0b0db5bf82 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/UserEntry.kt @@ -146,6 +146,7 @@ data class UserEntry( NSClientSource, PocTech, Tomato, + Glunovo, Xdrip, LocalProfile, //From LocalProfile plugin Loop, //From Loop plugin From ffa4120cd5278b637dd47579ba95f8698cb32618 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 9 Nov 2021 18:42:55 +0100 Subject: [PATCH 2/7] improve glunovo logic --- .../plugins/source/GlunovoPlugin.kt | 95 +++++++++++-------- app/src/main/res/values/strings.xml | 1 + 2 files changed, 59 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt index ed5ebc609d..cc2639e41e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -5,6 +5,7 @@ import android.net.Uri import android.os.Handler import android.os.HandlerThread import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.GlucoseValue @@ -15,13 +16,16 @@ import info.nightscout.androidaps.interfaces.PluginDescription import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.XDripBroadcast import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import io.reactivex.disposables.CompositeDisposable -import java.util.* import javax.inject.Inject import javax.inject.Singleton +import kotlin.math.min @Singleton class GlunovoPlugin @Inject constructor( @@ -31,7 +35,9 @@ class GlunovoPlugin @Inject constructor( private val sp: SP, private val context: Context, private val repository: AppRepository, - private val broadcastToXDrip: XDripBroadcast + private val broadcastToXDrip: XDripBroadcast, + private val dateUtil: DateUtil, + private val fabricPrivacy: FabricPrivacy ) : PluginBase( PluginDescription() .mainType(PluginType.BGSOURCE) @@ -51,8 +57,15 @@ class GlunovoPlugin @Inject constructor( init { refreshLoop = Runnable { - loopHandler.postDelayed(refreshLoop, INTERVAL) - handleNewData() + try { + handleNewData() + } catch (e: Exception) { + fabricPrivacy.logException(e) + aapsLogger.error("Error while processing data", e) + } + val lastReadTimestamp = sp.getLong(R.string.key_last_processed_glunovo_timestamp, 0L) + val differenceToNow = min(INTERVAL, dateUtil.now() - lastReadTimestamp + INTERVAL + T.secs(10).msecs()) + loopHandler.postDelayed(refreshLoop, differenceToNow) } } @@ -60,7 +73,7 @@ class GlunovoPlugin @Inject constructor( override fun onStart() { super.onStart() - loopHandler.postDelayed(refreshLoop, INTERVAL) + loopHandler.postDelayed(refreshLoop, T.secs(30).msecs()) // do not start immediately, app may be still starting } override fun onStop() { @@ -73,42 +86,50 @@ class GlunovoPlugin @Inject constructor( if (!isEnabled()) return context.contentResolver.query(contentUri, null, null, null, null)?.let { cr -> - cr.moveToLast() - val curTime = Calendar.getInstance().timeInMillis - val time = cr.getLong(0) - val value = cr.getDouble(1) //value in mmol/l... - if (time > curTime || time == 0L) { - aapsLogger.error(LTag.BGSOURCE, "Error in received data date/time $time") - return - } - - if (value < 2 || value > 25) { - aapsLogger.error(LTag.BGSOURCE, "Error in received data value (value out of bounds) $value") - return - } - val glucoseValues = mutableListOf() - glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( - timestamp = time, - value = value, - raw = 0.0, - noise = null, - trendArrow = GlucoseValue.TrendArrow.NONE, - sourceSensor = GlucoseValue.SourceSensor.GLUNOVO_NATIVE - ) - repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)) - .doOnError { - aapsLogger.error(LTag.DATABASE, "Error while saving values from Glunovo App", it) - } - .blockingGet() - .also { savedValues -> - savedValues.inserted.forEach { - broadcastToXDrip(it) - aapsLogger.debug(LTag.DATABASE, "Inserted bg $it") - } + cr.moveToFirst() + + while (!cr.isAfterLast) { + val timestamp = cr.getLong(0) + val value = cr.getDouble(1) //value in mmol/l... + if (timestamp > dateUtil.now() || timestamp == 0L) { + aapsLogger.error(LTag.BGSOURCE, "Error in received data date/time $timestamp") + continue } + if (value < 2 || value > 25) { + aapsLogger.error(LTag.BGSOURCE, "Error in received data value (value out of bounds) $value") + continue + } + + // bypass already processed + if (timestamp < sp.getLong(R.string.key_last_processed_glunovo_timestamp, 0L)) continue + + glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( + timestamp = timestamp, + value = value * Constants.MMOLL_TO_MGDL, + raw = 0.0, + noise = null, + trendArrow = GlucoseValue.TrendArrow.NONE, + sourceSensor = GlucoseValue.SourceSensor.GLUNOVO_NATIVE + ) + sp.putLong(R.string.key_last_processed_glunovo_timestamp, timestamp) + cr.moveToNext() + } cr.close() + + if (glucoseValues.isNotEmpty()) + repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)) + .doOnError { + aapsLogger.error(LTag.DATABASE, "Error while saving values from Glunovo App", it) + } + .blockingGet() + .also { savedValues -> + savedValues.inserted.forEach { + broadcastToXDrip(it) + aapsLogger.debug(LTag.DATABASE, "Inserted bg $it") + } + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f776a6b2de..1beca8f6d9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1134,5 +1134,6 @@ BG data status Recalculated data used BG too close:\n%1$s\n%2$s + last_processed_glunovo_timestamp From 56d97861e3522b6a53436f8895548c6d2bb50ea9 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 9 Nov 2021 20:22:33 +0100 Subject: [PATCH 3/7] fix glunovo loop --- .../nightscout/androidaps/plugins/source/GlunovoPlugin.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt index cc2639e41e..c15c4a6ce0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -94,16 +94,21 @@ class GlunovoPlugin @Inject constructor( val value = cr.getDouble(1) //value in mmol/l... if (timestamp > dateUtil.now() || timestamp == 0L) { aapsLogger.error(LTag.BGSOURCE, "Error in received data date/time $timestamp") + cr.moveToNext() continue } if (value < 2 || value > 25) { aapsLogger.error(LTag.BGSOURCE, "Error in received data value (value out of bounds) $value") + cr.moveToNext() continue } // bypass already processed - if (timestamp < sp.getLong(R.string.key_last_processed_glunovo_timestamp, 0L)) continue + if (timestamp < sp.getLong(R.string.key_last_processed_glunovo_timestamp, 0L)) { + cr.moveToNext() + continue + } glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( timestamp = timestamp, From bb7632aa806f66b78284c15348a2c6e5d3762f56 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 10 Nov 2021 12:25:07 +0100 Subject: [PATCH 4/7] Glunovo change schedule --- .../info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt index c15c4a6ce0..f8af965921 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -25,7 +25,6 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP import io.reactivex.disposables.CompositeDisposable import javax.inject.Inject import javax.inject.Singleton -import kotlin.math.min @Singleton class GlunovoPlugin @Inject constructor( @@ -64,7 +63,7 @@ class GlunovoPlugin @Inject constructor( aapsLogger.error("Error while processing data", e) } val lastReadTimestamp = sp.getLong(R.string.key_last_processed_glunovo_timestamp, 0L) - val differenceToNow = min(INTERVAL, dateUtil.now() - lastReadTimestamp + INTERVAL + T.secs(10).msecs()) + val differenceToNow = INTERVAL - (dateUtil.now() - lastReadTimestamp) % INTERVAL + T.secs(10).msecs() loopHandler.postDelayed(refreshLoop, differenceToNow) } } From 774beb2cb3cc6fb69c4a45eadbe176e5622aed53 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 11 Nov 2021 20:39:17 +0100 Subject: [PATCH 5/7] Glunovo process calibrations --- .../plugins/source/GlunovoPlugin.kt | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt index f8af965921..d2b6900836 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -9,6 +9,7 @@ import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.GlucoseValue +import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.transactions.CgmSourceTransaction import info.nightscout.androidaps.interfaces.BgSource import info.nightscout.androidaps.interfaces.PluginBase @@ -86,11 +87,13 @@ class GlunovoPlugin @Inject constructor( context.contentResolver.query(contentUri, null, null, null, null)?.let { cr -> val glucoseValues = mutableListOf() + val calibrations = mutableListOf() cr.moveToFirst() while (!cr.isAfterLast) { val timestamp = cr.getLong(0) val value = cr.getDouble(1) //value in mmol/l... + val curr = cr.getDouble(2) if (timestamp > dateUtil.now() || timestamp == 0L) { aapsLogger.error(LTag.BGSOURCE, "Error in received data date/time $timestamp") cr.moveToNext() @@ -109,21 +112,30 @@ class GlunovoPlugin @Inject constructor( continue } - glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( - timestamp = timestamp, - value = value * Constants.MMOLL_TO_MGDL, - raw = 0.0, - noise = null, - trendArrow = GlucoseValue.TrendArrow.NONE, - sourceSensor = GlucoseValue.SourceSensor.GLUNOVO_NATIVE - ) + if (curr != 0.0) + glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( + timestamp = timestamp, + value = value * Constants.MMOLL_TO_MGDL, + raw = 0.0, + noise = null, + trendArrow = GlucoseValue.TrendArrow.NONE, + sourceSensor = GlucoseValue.SourceSensor.GLUNOVO_NATIVE + ) + else + calibrations.add( + CgmSourceTransaction.Calibration( + timestamp = timestamp, + value = value, + glucoseUnit = TherapyEvent.GlucoseUnit.MMOL + ) + ) sp.putLong(R.string.key_last_processed_glunovo_timestamp, timestamp) cr.moveToNext() } cr.close() if (glucoseValues.isNotEmpty()) - repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)) + repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, calibrations, null)) .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving values from Glunovo App", it) } From 579c9dac7c4de41b36a4fed67494e0038d2196c7 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 11 Nov 2021 20:41:32 +0100 Subject: [PATCH 6/7] Glunovo rearrange --- .../androidaps/plugins/source/GlunovoPlugin.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt index d2b6900836..b541389895 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -94,6 +94,13 @@ class GlunovoPlugin @Inject constructor( val timestamp = cr.getLong(0) val value = cr.getDouble(1) //value in mmol/l... val curr = cr.getDouble(2) + + // bypass already processed + if (timestamp < sp.getLong(R.string.key_last_processed_glunovo_timestamp, 0L)) { + cr.moveToNext() + continue + } + if (timestamp > dateUtil.now() || timestamp == 0L) { aapsLogger.error(LTag.BGSOURCE, "Error in received data date/time $timestamp") cr.moveToNext() @@ -106,12 +113,6 @@ class GlunovoPlugin @Inject constructor( continue } - // bypass already processed - if (timestamp < sp.getLong(R.string.key_last_processed_glunovo_timestamp, 0L)) { - cr.moveToNext() - continue - } - if (curr != 0.0) glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( timestamp = timestamp, @@ -134,7 +135,7 @@ class GlunovoPlugin @Inject constructor( } cr.close() - if (glucoseValues.isNotEmpty()) + if (glucoseValues.isNotEmpty() || calibrations.isNotEmpty()) repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, calibrations, null)) .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving values from Glunovo App", it) From 01e70d978f9ed1f76e7ed8004f6f980e0badc7c1 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 12 Nov 2021 10:29:57 +0100 Subject: [PATCH 7/7] key not translatable --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1beca8f6d9..b622714e15 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1134,6 +1134,6 @@ BG data status Recalculated data used BG too close:\n%1$s\n%2$s - last_processed_glunovo_timestamp + last_processed_glunovo_timestamp