From f0c0b1b8076c2e9a55e120173f37cda97473b450 Mon Sep 17 00:00:00 2001 From: "xc.zheng" Date: Thu, 3 Sep 2026 11:41:39 +0800 Subject: [PATCH] Add glucose data source adapter for Sibionics CGM products --- app/src/main/AndroidManifest.xml | 2 + .../kotlin/app/aaps/di/PluginsListModule.kt | 7 ++ .../kotlin/app/aaps/receivers/DataReceiver.kt | 8 ++ .../app/aaps/core/data/model/SourceSensor.kt | 1 + .../kotlin/app/aaps/core/data/ue/Sources.kt | 1 + .../aaps/core/interfaces/receivers/Intents.kt | 3 + .../aaps/database/entities/GlucoseValue.kt | 1 + .../app/aaps/database/entities/UserEntry.kt | 1 + .../converters/SourceSensorExtension.kt | 2 + .../converters/SourcesExtension.kt | 2 + .../UserEntryPresentationHelperImpl.kt | 1 + .../aaps/plugins/source/SibionicsPlugin.kt | 94 +++++++++++++++++++ .../aaps/plugins/source/di/SourceModule.kt | 2 + .../src/main/res/values-zh-rCN/strings.xml | 3 + .../src/main/res/values-zh-rTW/strings.xml | 3 + .../source/src/main/res/values/strings.xml | 3 + 16 files changed, 134 insertions(+) create mode 100644 plugins/source/src/main/kotlin/app/aaps/plugins/source/SibionicsPlugin.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f69fc78c9763..2ac4f3f360b2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -103,6 +103,8 @@ + + diff --git a/app/src/main/kotlin/app/aaps/di/PluginsListModule.kt b/app/src/main/kotlin/app/aaps/di/PluginsListModule.kt index 4ad2be2d8acb..dda76a7b1241 100644 --- a/app/src/main/kotlin/app/aaps/di/PluginsListModule.kt +++ b/app/src/main/kotlin/app/aaps/di/PluginsListModule.kt @@ -44,6 +44,7 @@ import app.aaps.plugins.source.PatchedSiAppPlugin import app.aaps.plugins.source.PatchedSinoAppPlugin import app.aaps.plugins.source.PoctechPlugin import app.aaps.plugins.source.RandomBgPlugin +import app.aaps.plugins.source.SibionicsPlugin import app.aaps.plugins.source.SyaiPlugin import app.aaps.plugins.source.TomatoPlugin import app.aaps.plugins.source.XdripSourcePlugin @@ -451,6 +452,12 @@ abstract class PluginsListModule { @IntKey(476) abstract fun bindPatchedSinoAppPlugin(plugin: PatchedSinoAppPlugin): PluginBase + @Binds + @AllConfigs + @IntoMap + @IntKey(477) + abstract fun bindSibionicsPlugin(plugin: SibionicsPlugin): PluginBase + @Binds @AllConfigs @IntoMap diff --git a/app/src/main/kotlin/app/aaps/receivers/DataReceiver.kt b/app/src/main/kotlin/app/aaps/receivers/DataReceiver.kt index f44878cf0da8..8bd9c5baa52b 100644 --- a/app/src/main/kotlin/app/aaps/receivers/DataReceiver.kt +++ b/app/src/main/kotlin/app/aaps/receivers/DataReceiver.kt @@ -20,6 +20,7 @@ import app.aaps.plugins.source.DexcomPlugin import app.aaps.plugins.source.GlimpPlugin import app.aaps.plugins.source.MM640gPlugin import app.aaps.plugins.source.PatchedSiAppPlugin +import app.aaps.plugins.source.SibionicsPlugin import app.aaps.plugins.source.PatchedSinoAppPlugin import app.aaps.plugins.source.PoctechPlugin import app.aaps.plugins.source.SyaiPlugin @@ -91,6 +92,13 @@ open class DataReceiver : DaggerBroadcastReceiver() { it.copyString("data", bundle) }.build()).build() + Intents.SIB_APP -> + OneTimeWorkRequest.Builder(SibionicsPlugin.SibionicsWorker::class.java) + .setInputData(Data.Builder().also { + it.copyString("collection", bundle) + it.copyString("data", bundle) + }.build()).build() + Intents.SINO_APP -> OneTimeWorkRequest.Builder(PatchedSinoAppPlugin.PatchedSinoAppWorker::class.java) .setInputData(Data.Builder().also { diff --git a/core/data/src/main/kotlin/app/aaps/core/data/model/SourceSensor.kt b/core/data/src/main/kotlin/app/aaps/core/data/model/SourceSensor.kt index e697c0be57c1..d291e96cbebc 100644 --- a/core/data/src/main/kotlin/app/aaps/core/data/model/SourceSensor.kt +++ b/core/data/src/main/kotlin/app/aaps/core/data/model/SourceSensor.kt @@ -29,6 +29,7 @@ enum class SourceSensor(val text: String) { OTTAI("Ottai"), SIBIONIC_GS1_NATIVE("GS1 Native"), SIBIONIC("SI App"), + SIBIONICS("Sibionics"), SINO("Sino App"), EVERSENSE("Eversense"), AIDEX("GlucoRx Aidex"), diff --git a/core/data/src/main/kotlin/app/aaps/core/data/ue/Sources.kt b/core/data/src/main/kotlin/app/aaps/core/data/ue/Sources.kt index 96305b0294b0..3078b479d821 100644 --- a/core/data/src/main/kotlin/app/aaps/core/data/ue/Sources.kt +++ b/core/data/src/main/kotlin/app/aaps/core/data/ue/Sources.kt @@ -41,6 +41,7 @@ enum class Sources { SyaiTag, SiBionic, Sino, + Sibionics, //From SiBionics Plugin LocalProfile, //From LocalProfile plugin Loop, //From Loop plugin Maintenance, //From Maintenance plugin diff --git a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/receivers/Intents.kt b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/receivers/Intents.kt index 5ed152dd8548..44d66c74ddbf 100644 --- a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/receivers/Intents.kt +++ b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/receivers/Intents.kt @@ -56,5 +56,8 @@ interface Intents { const val SINO_APP = "cn.diyaps.sharing.SINO_APP" // Patched Syai Tag App -> AAPS const val SYAI_APP = "info.nightscout.androidaps.action.SYAI_TAG_APP" + + // Patched Sib App -> AAPS + const val SIB_APP = "com.diyaps.sharing.SIBIO_APP" } } diff --git a/database/impl/src/main/kotlin/app/aaps/database/entities/GlucoseValue.kt b/database/impl/src/main/kotlin/app/aaps/database/entities/GlucoseValue.kt index 2cfa2d735a3b..3a462b900abd 100644 --- a/database/impl/src/main/kotlin/app/aaps/database/entities/GlucoseValue.kt +++ b/database/impl/src/main/kotlin/app/aaps/database/entities/GlucoseValue.kt @@ -100,6 +100,7 @@ data class GlucoseValue( OTTAI, SIBIONIC_GS1_NATIVE, SIBIONIC, + SIBIONICS, SINO, SYAI_TAG, IOB_PREDICTION, diff --git a/database/impl/src/main/kotlin/app/aaps/database/entities/UserEntry.kt b/database/impl/src/main/kotlin/app/aaps/database/entities/UserEntry.kt index 77b6f3317023..3ed507c6d877 100644 --- a/database/impl/src/main/kotlin/app/aaps/database/entities/UserEntry.kt +++ b/database/impl/src/main/kotlin/app/aaps/database/entities/UserEntry.kt @@ -196,6 +196,7 @@ data class UserEntry( SyaiTag, //From Syai Tag plugin SiBionic, Sino, + Sibionics, // From Sibionics plugin Stats, //From Stat Activity Aaps, // MainApp BgFragment, diff --git a/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourceSensorExtension.kt b/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourceSensorExtension.kt index 8a7541682be4..8c6d70fa6956 100644 --- a/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourceSensorExtension.kt +++ b/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourceSensorExtension.kt @@ -39,6 +39,7 @@ fun GlucoseValue.SourceSensor.fromDb(): SourceSensor = GlucoseValue.SourceSensor.SIBIONIC_GS1_NATIVE -> SourceSensor.SIBIONIC_GS1_NATIVE GlucoseValue.SourceSensor.SIBIONIC -> SourceSensor.SIBIONIC GlucoseValue.SourceSensor.SINO -> SourceSensor.SINO + GlucoseValue.SourceSensor.SIBIONICS -> SourceSensor.SIBIONICS GlucoseValue.SourceSensor.IOB_PREDICTION -> SourceSensor.IOB_PREDICTION GlucoseValue.SourceSensor.A_COB_PREDICTION -> SourceSensor.A_COB_PREDICTION GlucoseValue.SourceSensor.COB_PREDICTION -> SourceSensor.COB_PREDICTION @@ -82,6 +83,7 @@ fun SourceSensor.toDb(): GlucoseValue.SourceSensor = SourceSensor.SIBIONIC_GS1_NATIVE -> GlucoseValue.SourceSensor.SIBIONIC_GS1_NATIVE SourceSensor.SIBIONIC -> GlucoseValue.SourceSensor.SIBIONIC SourceSensor.SINO -> GlucoseValue.SourceSensor.SINO + SourceSensor.SIBIONICS -> GlucoseValue.SourceSensor.SIBIONICS SourceSensor.IOB_PREDICTION -> GlucoseValue.SourceSensor.IOB_PREDICTION SourceSensor.A_COB_PREDICTION -> GlucoseValue.SourceSensor.A_COB_PREDICTION SourceSensor.COB_PREDICTION -> GlucoseValue.SourceSensor.COB_PREDICTION diff --git a/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourcesExtension.kt b/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourcesExtension.kt index e57afa55e610..41a72b756a05 100644 --- a/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourcesExtension.kt +++ b/database/persistence/src/main/kotlin/app/aaps/database/persistence/converters/SourcesExtension.kt @@ -45,6 +45,7 @@ fun UserEntry.Sources.fromDb(): Sources = UserEntry.Sources.SyaiTag -> Sources.SyaiTag UserEntry.Sources.SiBionic -> Sources.SiBionic UserEntry.Sources.Sino -> Sources.Sino + UserEntry.Sources.Sibionics -> Sources.Sibionics UserEntry.Sources.LocalProfile -> Sources.LocalProfile UserEntry.Sources.Loop -> Sources.Loop UserEntry.Sources.Maintenance -> Sources.Maintenance @@ -127,6 +128,7 @@ fun Sources.toDb(): UserEntry.Sources = Sources.SyaiTag -> UserEntry.Sources.SyaiTag Sources.SiBionic -> UserEntry.Sources.SiBionic Sources.Sino -> UserEntry.Sources.Sino + Sources.Sibionics -> UserEntry.Sources.Sibionics Sources.LocalProfile -> UserEntry.Sources.LocalProfile Sources.Loop -> UserEntry.Sources.Loop Sources.Maintenance -> UserEntry.Sources.Maintenance diff --git a/implementation/src/main/kotlin/app/aaps/implementation/userEntry/UserEntryPresentationHelperImpl.kt b/implementation/src/main/kotlin/app/aaps/implementation/userEntry/UserEntryPresentationHelperImpl.kt index ef5d2191a57f..8ba50248ce26 100644 --- a/implementation/src/main/kotlin/app/aaps/implementation/userEntry/UserEntryPresentationHelperImpl.kt +++ b/implementation/src/main/kotlin/app/aaps/implementation/userEntry/UserEntryPresentationHelperImpl.kt @@ -82,6 +82,7 @@ class UserEntryPresentationHelperImpl @Inject constructor( Sources.SyaiTag -> R.drawable.ic_syai_tag Sources.SiBionic -> R.drawable.ic_generic_cgm Sources.Sino -> R.drawable.ic_generic_cgm + Sources.Sibionics -> R.drawable.ic_generic_cgm Sources.LocalProfile -> R.drawable.ic_local_profile Sources.Loop -> R.drawable.ic_loop_closed_white Sources.Maintenance -> app.aaps.core.ui.R.drawable.ic_maintenance diff --git a/plugins/source/src/main/kotlin/app/aaps/plugins/source/SibionicsPlugin.kt b/plugins/source/src/main/kotlin/app/aaps/plugins/source/SibionicsPlugin.kt new file mode 100644 index 000000000000..1137c7c10ad8 --- /dev/null +++ b/plugins/source/src/main/kotlin/app/aaps/plugins/source/SibionicsPlugin.kt @@ -0,0 +1,94 @@ +package app.aaps.plugins.source + +import android.annotation.SuppressLint +import android.content.Context +import androidx.work.WorkerParameters +import androidx.work.workDataOf +import app.aaps.core.data.model.GV +import app.aaps.core.data.model.SourceSensor +import app.aaps.core.data.model.TrendArrow +import app.aaps.core.data.plugin.PluginType +import app.aaps.core.data.ue.Sources +import app.aaps.core.interfaces.db.PersistenceLayer +import app.aaps.core.interfaces.logging.AAPSLogger +import app.aaps.core.interfaces.logging.LTag +import app.aaps.core.interfaces.plugin.PluginDescription +import app.aaps.core.interfaces.resources.ResourceHelper +import app.aaps.core.interfaces.source.BgSource +import app.aaps.core.keys.interfaces.Preferences +import app.aaps.core.objects.workflow.LoggingWorker +import kotlinx.coroutines.Dispatchers +import org.json.JSONArray +import org.json.JSONException +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SibionicsPlugin @Inject constructor( + rh: ResourceHelper, + aapsLogger: AAPSLogger, + preferences: Preferences +) : AbstractBgSourcePlugin( + PluginDescription() + .mainType(PluginType.BGSOURCE) + .fragmentClass(BGSourceFragment::class.java.name) + .pluginIcon(app.aaps.core.objects.R.drawable.ic_generic_cgm) + .preferencesId(PluginDescription.PREFERENCE_SCREEN) + .pluginName(R.string.sibionics) + .preferencesVisibleInSimpleMode(false) + .description(R.string.description_source_sibionics), + ownPreferences = emptyList(), + aapsLogger, rh, preferences +), BgSource { + + class SibionicsWorker( + context: Context, + params: WorkerParameters + ) : LoggingWorker(context, params, Dispatchers.IO) { + + @Inject lateinit var sibionicsPlugin: SibionicsPlugin + @Inject lateinit var persistenceLayer: PersistenceLayer + + @SuppressLint("CheckResult") + override suspend fun doWorkAndLog(): Result { + var ret = Result.success() + if (!sibionicsPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled")) + val collection = inputData.getString("collection") ?: return Result.failure(workDataOf("Error" to "missing collection")) + if (collection == "entries") { + val data = inputData.getString("data") + aapsLogger.debug(LTag.BGSOURCE, "Received SIB App Data $data") + if (!data.isNullOrEmpty()) { + try { + val glucoseValues = mutableListOf() + val jsonArray = JSONArray(data) + for (i in 0 until jsonArray.length()) { + val jsonObject = jsonArray.getJSONObject(i) + when (val type = jsonObject.getString("type")) { + "sgv" -> + glucoseValues += GV( + timestamp = jsonObject.getLong("date"), + value = jsonObject.getDouble("sgv"), + raw = null, + noise = null, + trendArrow = TrendArrow.fromString(jsonObject.getString("direction")), + sourceSensor = SourceSensor.SIBIONICS + ) + + else -> aapsLogger.debug(LTag.BGSOURCE, "Unknown entries type: $type") + } + } + persistenceLayer.insertCgmSourceData(Sources.Sibionics, glucoseValues, emptyList(), null) + .doOnError { ret = Result.failure(workDataOf("Error" to it.toString())) } + .blockingGet() + } catch (e: JSONException) { + aapsLogger.error("Exception: ", e) + ret = Result.failure(workDataOf("Error" to e.toString())) + } + } + } else { + ret = Result.failure(workDataOf("Error" to "missing input data")) + } + return ret + } + } +} diff --git a/plugins/source/src/main/kotlin/app/aaps/plugins/source/di/SourceModule.kt b/plugins/source/src/main/kotlin/app/aaps/plugins/source/di/SourceModule.kt index 4c5ce92cc74a..abb9b0b5ede8 100644 --- a/plugins/source/src/main/kotlin/app/aaps/plugins/source/di/SourceModule.kt +++ b/plugins/source/src/main/kotlin/app/aaps/plugins/source/di/SourceModule.kt @@ -11,6 +11,7 @@ import app.aaps.plugins.source.NSClientSourcePlugin import app.aaps.plugins.source.PatchedSiAppPlugin import app.aaps.plugins.source.PatchedSinoAppPlugin import app.aaps.plugins.source.PoctechPlugin +import app.aaps.plugins.source.SibionicsPlugin import app.aaps.plugins.source.SyaiPlugin import app.aaps.plugins.source.TomatoPlugin import app.aaps.plugins.source.XdripSourcePlugin @@ -39,6 +40,7 @@ abstract class SourceModule { @ContributesAndroidInjector abstract fun contributesSyaiWorker(): SyaiPlugin.SyaiWorker @ContributesAndroidInjector abstract fun contributesSiAppWorker(): PatchedSiAppPlugin.PatchedSiAppWorker @ContributesAndroidInjector abstract fun contributesSinoAppWorker(): PatchedSinoAppPlugin.PatchedSinoAppWorker + @ContributesAndroidInjector abstract fun contributesSibionicsWorker(): SibionicsPlugin.SibionicsWorker @ContributesAndroidInjector abstract fun contributesRequestDexcomPermissionActivity(): RequestDexcomPermissionActivity diff --git a/plugins/source/src/main/res/values-zh-rCN/strings.xml b/plugins/source/src/main/res/values-zh-rCN/strings.xml index 946d3bbed5d2..211e074b63ea 100644 --- a/plugins/source/src/main/res/values-zh-rCN/strings.xml +++ b/plugins/source/src/main/res/values-zh-rCN/strings.xml @@ -24,4 +24,7 @@ 爱看补丁版 从爱看补丁版App接收血糖值。 + + 硅基(Sibionics) + 从硅基(Sibionics)应用接收血糖值 diff --git a/plugins/source/src/main/res/values-zh-rTW/strings.xml b/plugins/source/src/main/res/values-zh-rTW/strings.xml index f5b04987fb55..862ec1ee511a 100644 --- a/plugins/source/src/main/res/values-zh-rTW/strings.xml +++ b/plugins/source/src/main/res/values-zh-rTW/strings.xml @@ -39,4 +39,7 @@ Sino App 從修改版 Sino App 接收血糖資料。 + + 硅基(Sibionics) + 接收來自硅基(Sibionic)應用的血糖值 diff --git a/plugins/source/src/main/res/values/strings.xml b/plugins/source/src/main/res/values/strings.xml index c9b64f51b713..08e5d010b002 100644 --- a/plugins/source/src/main/res/values/strings.xml +++ b/plugins/source/src/main/res/values/strings.xml @@ -42,5 +42,8 @@ Sino App Receive glucose data from Patched Sino App. + + Sibionics + >Receive values from Sibionics App \ No newline at end of file