diff --git a/.idea/dictionaries/project_dictionary.xml b/.idea/dictionaries/project_dictionary.xml index 49af19275e..d167564b60 100644 --- a/.idea/dictionaries/project_dictionary.xml +++ b/.idea/dictionaries/project_dictionary.xml @@ -5,6 +5,7 @@ abcdef acked actionstring + aidex allowednumbers androidaps autosens @@ -105,4 +106,4 @@ ypsopump - \ No newline at end of file + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 84de1769b2..a4c3f20972 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -34,6 +34,10 @@ + + + + + + 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 57b39e4622..f4a679a9b0 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt @@ -87,6 +87,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang @Inject lateinit var poctechPlugin: PoctechPlugin @Inject lateinit var tomatoPlugin: TomatoPlugin @Inject lateinit var glunovoPlugin: GlunovoPlugin + @Inject lateinit var aidexPlugin: AidexPlugin @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin @Inject lateinit var statusLinePlugin: StatusLinePlugin @Inject lateinit var tidepoolPlugin: TidepoolPlugin @@ -163,6 +164,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang addPreferencesFromResourceIfEnabled(tomatoPlugin, rootKey) addPreferencesFromResourceIfEnabled(glunovoPlugin, rootKey) addPreferencesFromResourceIfEnabled(poctechPlugin, rootKey) + addPreferencesFromResourceIfEnabled(aidexPlugin, rootKey) addPreferencesFromResourceIfEnabled(glimpPlugin, rootKey) addPreferencesFromResourceIfEnabled(loopPlugin, rootKey, config.APS) addPreferencesFromResourceIfEnabled(openAPSAMAPlugin, rootKey, config.APS) @@ -447,4 +449,4 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang this.filter = filter preferenceManager?.preferenceScreen?.let { updateFilterVisibility(filter, it) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt b/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt index 127643b855..33259f2d18 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/PluginsModule.kt @@ -358,6 +358,12 @@ abstract class PluginsModule { @IntKey(460) abstract fun bindTomatoPlugin(plugin: TomatoPlugin): PluginBase + @Binds + @AllConfigs + @IntoMap + @IntKey(465) + abstract fun bindAidexPlugin(plugin: AidexPlugin): PluginBase + @Binds @AllConfigs @IntoMap diff --git a/app/src/main/java/info/nightscout/androidaps/di/WorkersModule.kt b/app/src/main/java/info/nightscout/androidaps/di/WorkersModule.kt index 92c84687b7..78991d111f 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/WorkersModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/WorkersModule.kt @@ -32,4 +32,5 @@ abstract class WorkersModule { @ContributesAndroidInjector abstract fun contributesNSClientMbgWorker(): NSClientMbgWorker @ContributesAndroidInjector abstract fun contributesFoodWorker(): FoodPlugin.FoodWorker @ContributesAndroidInjector abstract fun contributesCsvExportWorker(): ImportExportPrefsImpl.CsvExportWorker + @ContributesAndroidInjector abstract fun contributesAidexWorker(): AidexPlugin.AidexWorker } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt new file mode 100644 index 0000000000..d4cb82ce83 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt @@ -0,0 +1,111 @@ +package info.nightscout.androidaps.plugins.source + +import android.content.Context +import androidx.work.Worker +import androidx.work.WorkerParameters +import androidx.work.workDataOf +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 +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.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.receivers.DataWorker +import info.nightscout.androidaps.services.Intents +import info.nightscout.androidaps.utils.resources.ResourceHelper +import javax.inject.Inject +import javax.inject.Singleton +import kotlin.math.log + +@Singleton +class AidexPlugin @Inject constructor( + injector: HasAndroidInjector, + rh: ResourceHelper, + aapsLogger: AAPSLogger +) : PluginBase(PluginDescription() + .mainType(PluginType.BGSOURCE) + .fragmentClass(BGSourceFragment::class.java.name) + .pluginIcon((R.drawable.ic_blooddrop_48)) + .pluginName(R.string.aidex) + .shortName(R.string.aidex_short) + .description(R.string.description_source_aidex), + aapsLogger, rh, injector +), BgSource { + + private var advancedFiltering = false + + /** + * Aidex App doesn't have upload to NS + */ + override fun shouldUploadToNs(glucoseValue: GlucoseValue): Boolean = true + + override fun advancedFilteringSupported(): Boolean { + return advancedFiltering + } + + // cannot be inner class because of needed injection + class AidexWorker( + context: Context, + params: WorkerParameters + ) : Worker(context, params) { + + @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var aidexPlugin: AidexPlugin + @Inject lateinit var repository: AppRepository + @Inject lateinit var dataWorker: DataWorker + + init { + (context.applicationContext as HasAndroidInjector).androidInjector().inject(this) + } + + override fun doWork(): Result { + var ret = Result.success() + + if (!aidexPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled")) + val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1)) + ?: return Result.failure(workDataOf("Error" to "missing input data")) + + aapsLogger.debug(LTag.BGSOURCE, "Received Aidex data: $bundle") + + if (bundle.containsKey(Intents.AIDEX_TRANSMITTER_SN)) aapsLogger.debug(LTag.BGSOURCE, "transmitterSerialNumber: " + bundle.getString(Intents.AIDEX_TRANSMITTER_SN)) + if (bundle.containsKey(Intents.AIDEX_SENSOR_ID)) aapsLogger.debug(LTag.BGSOURCE, "sensorId: " + bundle.getString(Intents.AIDEX_SENSOR_ID)) + + val glucoseValues = mutableListOf() + + val timestamp = bundle.getLong(Intents.AIDEX_TIMESTAMP, 0) + val bgType = bundle.getString(Intents.AIDEX_BG_TYPE, "mg/dl") + val bgValue = bundle.getDouble(Intents.AIDEX_BG_VALUE, 0.0) + + val bgValueTarget = if (bgType.equals("mg/dl")) bgValue else bgValue * Constants.MMOLL_TO_MGDL + + aapsLogger.debug(LTag.BGSOURCE, "Received Aidex broadcast [time=$timestamp, bgType=$bgType, value=$bgValue, targetValue=$bgValueTarget") + + glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( + timestamp = timestamp, + value = bgValueTarget, + raw = null, + noise = null, + trendArrow = GlucoseValue.TrendArrow.fromString(bundle.getString(Intents.AIDEX_BG_SLOPE_NAME)), + sourceSensor = GlucoseValue.SourceSensor.AIDEX + ) + repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)) + .doOnError { + aapsLogger.error(LTag.DATABASE, "Error while saving values from Aidex", it) + ret = Result.failure(workDataOf("Error" to it.toString())) + } + .blockingGet() + .also { savedValues -> + savedValues.all().forEach { + aapsLogger.debug(LTag.DATABASE, "Inserted bg $it") + } + } + return ret + } + } +} 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 264a999eb8..ad6e0f867d 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 @@ -197,6 +197,7 @@ class BGSourceFragment : DaggerFragment() { R.string.tomato -> Sources.Tomato R.string.glunovo -> Sources.Glunovo R.string.xdrip -> Sources.Xdrip + R.string.aidex -> Sources.Aidex else -> Sources.Unknown } uel.log( diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.kt b/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.kt index 1326ec68c7..6bde38ee9a 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.kt +++ b/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.kt @@ -66,6 +66,9 @@ open class DataReceiver : DaggerBroadcastReceiver() { Intents.DEXCOM_BG -> OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java) .setInputData(dataWorker.storeInputData(bundle, intent)).build() + Intents.AIDEX_NEW_BG_ESTIMATE -> + OneTimeWorkRequest.Builder(AidexPlugin.AidexWorker::class.java) + .setInputData(dataWorker.storeInputData(bundle, intent)).build() else -> null }?.let { request -> dataWorker.enqueue(request) } } diff --git a/app/src/main/java/info/nightscout/androidaps/services/Intents.kt b/app/src/main/java/info/nightscout/androidaps/services/Intents.kt index bf3a8d3695..925c74eff8 100644 --- a/app/src/main/java/info/nightscout/androidaps/services/Intents.kt +++ b/app/src/main/java/info/nightscout/androidaps/services/Intents.kt @@ -31,6 +31,15 @@ interface Intents { const val POCTECH_BG = "com.china.poctech.data" const val TOMATO_BG = "com.fanqies.tomatofn.BgEstimate" + // Aidex -> AAPS + var AIDEX_NEW_BG_ESTIMATE = "com.microtechmd.cgms.aidex.action.BgEstimate" + var AIDEX_BG_TYPE = "com.microtechmd.cgms.aidex.BgType" + var AIDEX_BG_VALUE = "com.microtechmd.cgms.aidex.BgValue" + var AIDEX_BG_SLOPE_NAME = "com.microtechmd.cgms.aidex.BgSlopeName" + var AIDEX_TIMESTAMP = "com.microtechmd.cgms.aidex.Time" // epoch in ms + var AIDEX_TRANSMITTER_SN = "com.microtechmd.cgms.aidex.TransmitterSerialNumber" + var AIDEX_SENSOR_ID = "com.microtechmd.cgms.aidex.SensorId" + // Broadcast status const val AAPS_BROADCAST = "info.nightscout.androidaps.status" } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 12e9f6b607..6aa775cad1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1212,6 +1212,7 @@ Hide loop records AndroidAPS widget Configure opacity + QR Code for setup one time password open settings set carb timer alarm @@ -1221,4 +1222,10 @@ only on watch only on phone drag and drop handle + + + GlucoRx Aidex + Aidex + Receive BG values from GlucoRx Aidex CGMS. + diff --git a/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt b/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt index d680f5e3f3..c386e0703c 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt @@ -255,6 +255,7 @@ class Translator @Inject internal constructor( Sources.MM640g -> TODO() Sources.NSClientSource -> TODO() Sources.PocTech -> TODO() + Sources.Aidex -> TODO() Sources.Tomato -> TODO() Sources.Xdrip -> TODO() Sources.LocalProfile -> TODO() @@ -293,4 +294,4 @@ class Translator @Inject internal constructor( else -> source.name } -} \ No newline at end of file +} diff --git a/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryMapper.kt b/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryMapper.kt index fb667823e4..9f2333fbd9 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryMapper.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryMapper.kt @@ -109,6 +109,7 @@ class UserEntryMapper { Actions (UserEntry.Sources.Actions), Automation (UserEntry.Sources.Automation), BG (UserEntry.Sources.BG), + Aidex (UserEntry.Sources.Aidex), Dexcom (UserEntry.Sources.Dexcom), Eversense (UserEntry.Sources.Eversense), Glimp (UserEntry.Sources.Glimp), @@ -150,4 +151,4 @@ class UserEntryMapper { Unknown(UserEntry.Sources.Unknown) ; } -} \ No newline at end of file +} 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 f462c0f209..9f2daa57b4 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 @@ -63,6 +63,7 @@ class UserEntryPresentationHelper @Inject constructor( Sources.Actions -> R.drawable.ic_action Sources.Automation -> R.drawable.ic_automation Sources.BG -> R.drawable.ic_generic_cgm + Sources.Aidex -> R.drawable.ic_blooddrop_48 Sources.Dexcom -> R.drawable.ic_dexcom_g6 Sources.Eversense -> R.drawable.ic_eversense Sources.Glimp -> R.drawable.ic_glimp @@ -226,4 +227,4 @@ class UserEntryPresentationHelper @Inject constructor( private fun String.addWithSeparator(add: Any) = this + (if (this.isBlank()) "" else " / ") + add.toString() -} \ No newline at end of file +} 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 241485a254..00979a554c 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 @@ -111,6 +111,7 @@ data class GlucoseValue( GLUNOVO_NATIVE("Glunovo"), MM_600_SERIES("MM600Series"), EVERSENSE("Eversense"), + AIDEX("GlucoRx Aidex"), RANDOM("Random"), UNKNOWN("Unknown"), 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 0b0db5bf82..f6c3d39234 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 @@ -139,6 +139,7 @@ data class UserEntry( Actions, //From Actions plugin Automation, //From Automation plugin BG, //From BG plugin => Add One Source per BG Source for Calibration or Sensor Change + Aidex, Dexcom, Eversense, Glimp, @@ -197,4 +198,4 @@ data class UserEntry( Pump, Aaps } -} \ No newline at end of file +}