Merge pull request #1650 from andyrozman/aidex_support_v2
Aidex support v2
This commit is contained in:
commit
7c576338c6
15 changed files with 158 additions and 6 deletions
|
@ -5,6 +5,7 @@
|
||||||
<w>abcdef</w>
|
<w>abcdef</w>
|
||||||
<w>acked</w>
|
<w>acked</w>
|
||||||
<w>actionstring</w>
|
<w>actionstring</w>
|
||||||
|
<w>aidex</w>
|
||||||
<w>allowednumbers</w>
|
<w>allowednumbers</w>
|
||||||
<w>androidaps</w>
|
<w>androidaps</w>
|
||||||
<w>autosens</w>
|
<w>autosens</w>
|
||||||
|
@ -105,4 +106,4 @@
|
||||||
<w>ypsopump</w>
|
<w>ypsopump</w>
|
||||||
</words>
|
</words>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
<!-- To receive data from xdrip. -->
|
<!-- To receive data from xdrip. -->
|
||||||
<uses-permission android:name="com.eveningoutpost.dexdrip.permissions.RECEIVE_BG_ESTIMATE" />
|
<uses-permission android:name="com.eveningoutpost.dexdrip.permissions.RECEIVE_BG_ESTIMATE" />
|
||||||
|
|
||||||
|
<!-- To receive data from Aidex -->
|
||||||
|
<uses-permission android:name="com.microtechmd.cgms.aidex.permissions.RECEIVE_BG_ESTIMATE" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApp"
|
android:name=".MainApp"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -133,6 +137,8 @@
|
||||||
<action android:name="com.china.poctech.data"/>
|
<action android:name="com.china.poctech.data"/>
|
||||||
<!-- Receiver from Tomato -->
|
<!-- Receiver from Tomato -->
|
||||||
<action android:name="com.fanqies.tomatofn.BgEstimate"/>
|
<action android:name="com.fanqies.tomatofn.BgEstimate"/>
|
||||||
|
<!-- Receiver from GlucoRx Aidex -->
|
||||||
|
<action android:name="com.microtechmd.cgms.aidex.action.BgEstimate"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
||||||
@Inject lateinit var poctechPlugin: PoctechPlugin
|
@Inject lateinit var poctechPlugin: PoctechPlugin
|
||||||
@Inject lateinit var tomatoPlugin: TomatoPlugin
|
@Inject lateinit var tomatoPlugin: TomatoPlugin
|
||||||
@Inject lateinit var glunovoPlugin: GlunovoPlugin
|
@Inject lateinit var glunovoPlugin: GlunovoPlugin
|
||||||
|
@Inject lateinit var aidexPlugin: AidexPlugin
|
||||||
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
|
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
|
||||||
@Inject lateinit var statusLinePlugin: StatusLinePlugin
|
@Inject lateinit var statusLinePlugin: StatusLinePlugin
|
||||||
@Inject lateinit var tidepoolPlugin: TidepoolPlugin
|
@Inject lateinit var tidepoolPlugin: TidepoolPlugin
|
||||||
|
@ -163,6 +164,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
||||||
addPreferencesFromResourceIfEnabled(tomatoPlugin, rootKey)
|
addPreferencesFromResourceIfEnabled(tomatoPlugin, rootKey)
|
||||||
addPreferencesFromResourceIfEnabled(glunovoPlugin, rootKey)
|
addPreferencesFromResourceIfEnabled(glunovoPlugin, rootKey)
|
||||||
addPreferencesFromResourceIfEnabled(poctechPlugin, rootKey)
|
addPreferencesFromResourceIfEnabled(poctechPlugin, rootKey)
|
||||||
|
addPreferencesFromResourceIfEnabled(aidexPlugin, rootKey)
|
||||||
addPreferencesFromResourceIfEnabled(glimpPlugin, rootKey)
|
addPreferencesFromResourceIfEnabled(glimpPlugin, rootKey)
|
||||||
addPreferencesFromResourceIfEnabled(loopPlugin, rootKey, config.APS)
|
addPreferencesFromResourceIfEnabled(loopPlugin, rootKey, config.APS)
|
||||||
addPreferencesFromResourceIfEnabled(openAPSAMAPlugin, rootKey, config.APS)
|
addPreferencesFromResourceIfEnabled(openAPSAMAPlugin, rootKey, config.APS)
|
||||||
|
@ -447,4 +449,4 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
||||||
this.filter = filter
|
this.filter = filter
|
||||||
preferenceManager?.preferenceScreen?.let { updateFilterVisibility(filter, it) }
|
preferenceManager?.preferenceScreen?.let { updateFilterVisibility(filter, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,6 +358,12 @@ abstract class PluginsModule {
|
||||||
@IntKey(460)
|
@IntKey(460)
|
||||||
abstract fun bindTomatoPlugin(plugin: TomatoPlugin): PluginBase
|
abstract fun bindTomatoPlugin(plugin: TomatoPlugin): PluginBase
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@AllConfigs
|
||||||
|
@IntoMap
|
||||||
|
@IntKey(465)
|
||||||
|
abstract fun bindAidexPlugin(plugin: AidexPlugin): PluginBase
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@AllConfigs
|
@AllConfigs
|
||||||
@IntoMap
|
@IntoMap
|
||||||
|
|
|
@ -32,4 +32,5 @@ abstract class WorkersModule {
|
||||||
@ContributesAndroidInjector abstract fun contributesNSClientMbgWorker(): NSClientMbgWorker
|
@ContributesAndroidInjector abstract fun contributesNSClientMbgWorker(): NSClientMbgWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesFoodWorker(): FoodPlugin.FoodWorker
|
@ContributesAndroidInjector abstract fun contributesFoodWorker(): FoodPlugin.FoodWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesCsvExportWorker(): ImportExportPrefsImpl.CsvExportWorker
|
@ContributesAndroidInjector abstract fun contributesCsvExportWorker(): ImportExportPrefsImpl.CsvExportWorker
|
||||||
|
@ContributesAndroidInjector abstract fun contributesAidexWorker(): AidexPlugin.AidexWorker
|
||||||
}
|
}
|
|
@ -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<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -197,6 +197,7 @@ class BGSourceFragment : DaggerFragment() {
|
||||||
R.string.tomato -> Sources.Tomato
|
R.string.tomato -> Sources.Tomato
|
||||||
R.string.glunovo -> Sources.Glunovo
|
R.string.glunovo -> Sources.Glunovo
|
||||||
R.string.xdrip -> Sources.Xdrip
|
R.string.xdrip -> Sources.Xdrip
|
||||||
|
R.string.aidex -> Sources.Aidex
|
||||||
else -> Sources.Unknown
|
else -> Sources.Unknown
|
||||||
}
|
}
|
||||||
uel.log(
|
uel.log(
|
||||||
|
|
|
@ -66,6 +66,9 @@ open class DataReceiver : DaggerBroadcastReceiver() {
|
||||||
Intents.DEXCOM_BG ->
|
Intents.DEXCOM_BG ->
|
||||||
OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java)
|
OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java)
|
||||||
.setInputData(dataWorker.storeInputData(bundle, intent)).build()
|
.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
|
else -> null
|
||||||
}?.let { request -> dataWorker.enqueue(request) }
|
}?.let { request -> dataWorker.enqueue(request) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,15 @@ interface Intents {
|
||||||
const val POCTECH_BG = "com.china.poctech.data"
|
const val POCTECH_BG = "com.china.poctech.data"
|
||||||
const val TOMATO_BG = "com.fanqies.tomatofn.BgEstimate"
|
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
|
// Broadcast status
|
||||||
const val AAPS_BROADCAST = "info.nightscout.androidaps.status"
|
const val AAPS_BROADCAST = "info.nightscout.androidaps.status"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1212,6 +1212,7 @@
|
||||||
<string name="show_hide_records">Hide loop records</string>
|
<string name="show_hide_records">Hide loop records</string>
|
||||||
<string name="widget_description">AndroidAPS widget</string>
|
<string name="widget_description">AndroidAPS widget</string>
|
||||||
<string name="configure">Configure opacity</string>
|
<string name="configure">Configure opacity</string>
|
||||||
|
|
||||||
<string name="a11y_otp_qr_code">QR Code for setup one time password</string>
|
<string name="a11y_otp_qr_code">QR Code for setup one time password</string>
|
||||||
<string name="a11y_open_settings">open settings</string>
|
<string name="a11y_open_settings">open settings</string>
|
||||||
<string name="a11y_set_carb_timer">set carb timer alarm</string>
|
<string name="a11y_set_carb_timer">set carb timer alarm</string>
|
||||||
|
@ -1221,4 +1222,10 @@
|
||||||
<string name="a11y_only_on_watch">only on watch</string>
|
<string name="a11y_only_on_watch">only on watch</string>
|
||||||
<string name="a11y_only_on_phone">only on phone</string>
|
<string name="a11y_only_on_phone">only on phone</string>
|
||||||
<string name="a11y_drag_and_drop_handle">drag and drop handle</string>
|
<string name="a11y_drag_and_drop_handle">drag and drop handle</string>
|
||||||
|
|
||||||
|
<!-- Aidex Cgms -->
|
||||||
|
<string name="aidex">GlucoRx Aidex</string>
|
||||||
|
<string name="aidex_short">Aidex</string>
|
||||||
|
<string name="description_source_aidex">Receive BG values from GlucoRx Aidex CGMS.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -255,6 +255,7 @@ class Translator @Inject internal constructor(
|
||||||
Sources.MM640g -> TODO()
|
Sources.MM640g -> TODO()
|
||||||
Sources.NSClientSource -> TODO()
|
Sources.NSClientSource -> TODO()
|
||||||
Sources.PocTech -> TODO()
|
Sources.PocTech -> TODO()
|
||||||
|
Sources.Aidex -> TODO()
|
||||||
Sources.Tomato -> TODO()
|
Sources.Tomato -> TODO()
|
||||||
Sources.Xdrip -> TODO()
|
Sources.Xdrip -> TODO()
|
||||||
Sources.LocalProfile -> TODO()
|
Sources.LocalProfile -> TODO()
|
||||||
|
@ -293,4 +294,4 @@ class Translator @Inject internal constructor(
|
||||||
|
|
||||||
else -> source.name
|
else -> source.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,7 @@ class UserEntryMapper {
|
||||||
Actions (UserEntry.Sources.Actions),
|
Actions (UserEntry.Sources.Actions),
|
||||||
Automation (UserEntry.Sources.Automation),
|
Automation (UserEntry.Sources.Automation),
|
||||||
BG (UserEntry.Sources.BG),
|
BG (UserEntry.Sources.BG),
|
||||||
|
Aidex (UserEntry.Sources.Aidex),
|
||||||
Dexcom (UserEntry.Sources.Dexcom),
|
Dexcom (UserEntry.Sources.Dexcom),
|
||||||
Eversense (UserEntry.Sources.Eversense),
|
Eversense (UserEntry.Sources.Eversense),
|
||||||
Glimp (UserEntry.Sources.Glimp),
|
Glimp (UserEntry.Sources.Glimp),
|
||||||
|
@ -150,4 +151,4 @@ class UserEntryMapper {
|
||||||
Unknown(UserEntry.Sources.Unknown)
|
Unknown(UserEntry.Sources.Unknown)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ class UserEntryPresentationHelper @Inject constructor(
|
||||||
Sources.Actions -> R.drawable.ic_action
|
Sources.Actions -> R.drawable.ic_action
|
||||||
Sources.Automation -> R.drawable.ic_automation
|
Sources.Automation -> R.drawable.ic_automation
|
||||||
Sources.BG -> R.drawable.ic_generic_cgm
|
Sources.BG -> R.drawable.ic_generic_cgm
|
||||||
|
Sources.Aidex -> R.drawable.ic_blooddrop_48
|
||||||
Sources.Dexcom -> R.drawable.ic_dexcom_g6
|
Sources.Dexcom -> R.drawable.ic_dexcom_g6
|
||||||
Sources.Eversense -> R.drawable.ic_eversense
|
Sources.Eversense -> R.drawable.ic_eversense
|
||||||
Sources.Glimp -> R.drawable.ic_glimp
|
Sources.Glimp -> R.drawable.ic_glimp
|
||||||
|
@ -226,4 +227,4 @@ class UserEntryPresentationHelper @Inject constructor(
|
||||||
|
|
||||||
private fun String.addWithSeparator(add: Any) =
|
private fun String.addWithSeparator(add: Any) =
|
||||||
this + (if (this.isBlank()) "" else " / ") + add.toString()
|
this + (if (this.isBlank()) "" else " / ") + add.toString()
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,7 @@ data class GlucoseValue(
|
||||||
GLUNOVO_NATIVE("Glunovo"),
|
GLUNOVO_NATIVE("Glunovo"),
|
||||||
MM_600_SERIES("MM600Series"),
|
MM_600_SERIES("MM600Series"),
|
||||||
EVERSENSE("Eversense"),
|
EVERSENSE("Eversense"),
|
||||||
|
AIDEX("GlucoRx Aidex"),
|
||||||
RANDOM("Random"),
|
RANDOM("Random"),
|
||||||
UNKNOWN("Unknown"),
|
UNKNOWN("Unknown"),
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,7 @@ data class UserEntry(
|
||||||
Actions, //From Actions plugin
|
Actions, //From Actions plugin
|
||||||
Automation, //From Automation plugin
|
Automation, //From Automation plugin
|
||||||
BG, //From BG plugin => Add One Source per BG Source for Calibration or Sensor Change
|
BG, //From BG plugin => Add One Source per BG Source for Calibration or Sensor Change
|
||||||
|
Aidex,
|
||||||
Dexcom,
|
Dexcom,
|
||||||
Eversense,
|
Eversense,
|
||||||
Glimp,
|
Glimp,
|
||||||
|
@ -197,4 +198,4 @@ data class UserEntry(
|
||||||
Pump,
|
Pump,
|
||||||
Aaps
|
Aaps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue