Empty plugin
This commit is contained in:
parent
1920bc7ce5
commit
18be54f489
|
@ -214,6 +214,7 @@ dependencies {
|
||||||
implementation project(':pump:danar')
|
implementation project(':pump:danar')
|
||||||
implementation project(':pump:diaconn')
|
implementation project(':pump:diaconn')
|
||||||
implementation project(':pump:eopatch')
|
implementation project(':pump:eopatch')
|
||||||
|
implementation project(':pump:medtrum')
|
||||||
implementation project(':insight')
|
implementation project(':insight')
|
||||||
implementation project(':pump:medtronic')
|
implementation project(':pump:medtronic')
|
||||||
implementation project(':pump:pump-common')
|
implementation project(':pump:pump-common')
|
||||||
|
|
|
@ -54,6 +54,7 @@ import info.nightscout.plugins.sync.xdrip.XdripPlugin
|
||||||
import info.nightscout.pump.combo.ComboPlugin
|
import info.nightscout.pump.combo.ComboPlugin
|
||||||
import info.nightscout.pump.combov2.ComboV2Plugin
|
import info.nightscout.pump.combov2.ComboV2Plugin
|
||||||
import info.nightscout.pump.diaconn.DiaconnG8Plugin
|
import info.nightscout.pump.diaconn.DiaconnG8Plugin
|
||||||
|
import info.nightscout.pump.medtrum.MedtrumPumpPlugin
|
||||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.rx.bus.RxBus
|
import info.nightscout.rx.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventPreferenceChange
|
import info.nightscout.rx.events.EventPreferenceChange
|
||||||
|
@ -122,6 +123,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
||||||
@Inject lateinit var wearPlugin: WearPlugin
|
@Inject lateinit var wearPlugin: WearPlugin
|
||||||
@Inject lateinit var maintenancePlugin: MaintenancePlugin
|
@Inject lateinit var maintenancePlugin: MaintenancePlugin
|
||||||
@Inject lateinit var eopatchPumpPlugin: EopatchPumpPlugin
|
@Inject lateinit var eopatchPumpPlugin: EopatchPumpPlugin
|
||||||
|
@Inject lateinit var medtrumPumpPlugin: MedtrumPumpPlugin
|
||||||
|
|
||||||
@Inject lateinit var passwordCheck: PasswordCheck
|
@Inject lateinit var passwordCheck: PasswordCheck
|
||||||
@Inject lateinit var nsSettingStatus: NSSettingsStatus
|
@Inject lateinit var nsSettingStatus: NSSettingsStatus
|
||||||
|
@ -212,6 +214,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
||||||
addPreferencesFromResourceIfEnabled(medtronicPumpPlugin, rootKey, config.PUMPDRIVERS)
|
addPreferencesFromResourceIfEnabled(medtronicPumpPlugin, rootKey, config.PUMPDRIVERS)
|
||||||
addPreferencesFromResourceIfEnabled(diaconnG8Plugin, rootKey, config.PUMPDRIVERS)
|
addPreferencesFromResourceIfEnabled(diaconnG8Plugin, rootKey, config.PUMPDRIVERS)
|
||||||
addPreferencesFromResourceIfEnabled(eopatchPumpPlugin, rootKey, config.PUMPDRIVERS)
|
addPreferencesFromResourceIfEnabled(eopatchPumpPlugin, rootKey, config.PUMPDRIVERS)
|
||||||
|
addPreferencesFromResourceIfEnabled(medtrumPumpPlugin, rootKey, config.PUMPDRIVERS)
|
||||||
addPreferencesFromResource(R.xml.pref_pump, rootKey, config.PUMPDRIVERS)
|
addPreferencesFromResource(R.xml.pref_pump, rootKey, config.PUMPDRIVERS)
|
||||||
addPreferencesFromResourceIfEnabled(virtualPumpPlugin, rootKey)
|
addPreferencesFromResourceIfEnabled(virtualPumpPlugin, rootKey)
|
||||||
addPreferencesFromResourceIfEnabled(insulinOrefFreePeakPlugin, rootKey)
|
addPreferencesFromResourceIfEnabled(insulinOrefFreePeakPlugin, rootKey)
|
||||||
|
|
|
@ -33,6 +33,7 @@ import info.nightscout.pump.dana.di.DanaModule
|
||||||
import info.nightscout.pump.danars.di.DanaRSModule
|
import info.nightscout.pump.danars.di.DanaRSModule
|
||||||
import info.nightscout.pump.diaconn.di.DiaconnG8Module
|
import info.nightscout.pump.diaconn.di.DiaconnG8Module
|
||||||
import info.nightscout.pump.virtual.di.VirtualPumpModule
|
import info.nightscout.pump.virtual.di.VirtualPumpModule
|
||||||
|
import info.nightscout.pump.medtrum.di.MedtrumPumpModule
|
||||||
import info.nightscout.rx.di.RxModule
|
import info.nightscout.rx.di.RxModule
|
||||||
import info.nightscout.shared.di.SharedModule
|
import info.nightscout.shared.di.SharedModule
|
||||||
import info.nightscout.shared.impl.di.SharedImplModule
|
import info.nightscout.shared.impl.di.SharedImplModule
|
||||||
|
@ -87,6 +88,7 @@ import javax.inject.Singleton
|
||||||
OmnipodErosModule::class,
|
OmnipodErosModule::class,
|
||||||
PumpCommonModule::class,
|
PumpCommonModule::class,
|
||||||
RileyLinkModule::class,
|
RileyLinkModule::class,
|
||||||
|
MedtrumPumpModule::class,
|
||||||
VirtualPumpModule::class
|
VirtualPumpModule::class
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -46,6 +46,7 @@ import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
|
||||||
import info.nightscout.plugins.sync.xdrip.XdripPlugin
|
import info.nightscout.plugins.sync.xdrip.XdripPlugin
|
||||||
import info.nightscout.pump.combo.ComboPlugin
|
import info.nightscout.pump.combo.ComboPlugin
|
||||||
import info.nightscout.pump.combov2.ComboV2Plugin
|
import info.nightscout.pump.combov2.ComboV2Plugin
|
||||||
|
import info.nightscout.pump.medtrum.MedtrumPumpPlugin
|
||||||
import info.nightscout.pump.diaconn.DiaconnG8Plugin
|
import info.nightscout.pump.diaconn.DiaconnG8Plugin
|
||||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.sensitivity.SensitivityAAPSPlugin
|
import info.nightscout.sensitivity.SensitivityAAPSPlugin
|
||||||
|
@ -209,6 +210,12 @@ abstract class PluginsListModule {
|
||||||
@IntKey(156)
|
@IntKey(156)
|
||||||
abstract fun bindEopatchPumpPlugin(plugin: EopatchPumpPlugin): PluginBase
|
abstract fun bindEopatchPumpPlugin(plugin: EopatchPumpPlugin): PluginBase
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@PumpDriver
|
||||||
|
@IntoMap
|
||||||
|
@IntKey(160)
|
||||||
|
abstract fun bindMedtrumPumpPlugin(plugin: MedtrumPumpPlugin): PluginBase
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@AllConfigs
|
@AllConfigs
|
||||||
@IntoMap
|
@IntoMap
|
||||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.interfaces.pump.defs
|
||||||
|
|
||||||
enum class ManufacturerType(val description: String) {
|
enum class ManufacturerType(val description: String) {
|
||||||
AAPS("AAPS"),
|
AAPS("AAPS"),
|
||||||
|
Medtrum("Medtrum"),
|
||||||
Medtronic("Medtronic"),
|
Medtronic("Medtronic"),
|
||||||
Sooil("SOOIL"),
|
Sooil("SOOIL"),
|
||||||
Tandem("Tandem"),
|
Tandem("Tandem"),
|
||||||
|
|
1
pump/medtrum/.gitignore
vendored
Normal file
1
pump/medtrum/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
27
pump/medtrum/build.gradle
Normal file
27
pump/medtrum/build.gradle
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
plugins {
|
||||||
|
id 'com.android.library'
|
||||||
|
id 'kotlin-android'
|
||||||
|
id 'kotlin-kapt'
|
||||||
|
id 'kotlin-allopen'
|
||||||
|
id 'com.hiya.jacoco-android'
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "${project.rootDir}/core/main/android_dependencies.gradle"
|
||||||
|
apply from: "${project.rootDir}/core/main/android_module_dependencies.gradle"
|
||||||
|
apply from: "${project.rootDir}/core/main/allopen_dependencies.gradle"
|
||||||
|
apply from: "${project.rootDir}/core/main/test_dependencies.gradle"
|
||||||
|
apply from: "${project.rootDir}/core/main/jacoco_global.gradle"
|
||||||
|
|
||||||
|
android {
|
||||||
|
|
||||||
|
namespace 'info.nightscout.pump.medtrum'
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':app-wear-shared:shared')
|
||||||
|
implementation project(':database:entities')
|
||||||
|
implementation project(':core:interfaces')
|
||||||
|
implementation project(':core:main')
|
||||||
|
implementation project(':core:ui')
|
||||||
|
implementation project(':core:utils')
|
||||||
|
}
|
0
pump/medtrum/consumer-rules.pro
Normal file
0
pump/medtrum/consumer-rules.pro
Normal file
21
pump/medtrum/proguard-rules.pro
vendored
Normal file
21
pump/medtrum/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
3
pump/medtrum/src/main/AndroidManifest.xml
Normal file
3
pump/medtrum/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
</manifest>
|
|
@ -0,0 +1,219 @@
|
||||||
|
package info.nightscout.pump.medtrum
|
||||||
|
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
|
import info.nightscout.interfaces.profile.Profile
|
||||||
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
|
import info.nightscout.interfaces.pump.DetailedBolusInfo
|
||||||
|
import info.nightscout.interfaces.pump.Pump
|
||||||
|
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||||
|
import info.nightscout.interfaces.pump.PumpPluginBase
|
||||||
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
|
import info.nightscout.interfaces.pump.actions.CustomAction
|
||||||
|
import info.nightscout.interfaces.pump.actions.CustomActionType
|
||||||
|
import info.nightscout.interfaces.pump.defs.ManufacturerType
|
||||||
|
import info.nightscout.interfaces.pump.defs.PumpDescription
|
||||||
|
import info.nightscout.interfaces.pump.defs.PumpType
|
||||||
|
import info.nightscout.interfaces.queue.CommandQueue
|
||||||
|
import info.nightscout.interfaces.queue.CustomCommand
|
||||||
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
|
import info.nightscout.interfaces.utils.TimeChangeType
|
||||||
|
import info.nightscout.pump.medtrum.ui.MedtrumPumpFragment
|
||||||
|
import info.nightscout.rx.AapsSchedulers
|
||||||
|
import info.nightscout.rx.bus.RxBus
|
||||||
|
import info.nightscout.rx.events.EventAppInitialized
|
||||||
|
import info.nightscout.rx.events.EventOverviewBolusProgress
|
||||||
|
import info.nightscout.rx.events.EventPreferenceChange
|
||||||
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
|
import info.nightscout.rx.logging.LTag
|
||||||
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
import info.nightscout.shared.utils.T
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxjava3.functions.Consumer
|
||||||
|
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class MedtrumPumpPlugin @Inject constructor(
|
||||||
|
injector: HasAndroidInjector,
|
||||||
|
aapsLogger: AAPSLogger,
|
||||||
|
rh: ResourceHelper,
|
||||||
|
commandQueue: CommandQueue,
|
||||||
|
private val aapsSchedulers: AapsSchedulers,
|
||||||
|
private val rxBus: RxBus,
|
||||||
|
private val fabricPrivacy: FabricPrivacy,
|
||||||
|
private val dateUtil: DateUtil,
|
||||||
|
private val pumpSync: PumpSync,
|
||||||
|
private val uiInteraction: UiInteraction,
|
||||||
|
private val profileFunction: ProfileFunction
|
||||||
|
) : PumpPluginBase(
|
||||||
|
PluginDescription()
|
||||||
|
.mainType(PluginType.PUMP) // TODO Prefs etc
|
||||||
|
.fragmentClass(MedtrumPumpFragment::class.java.name)
|
||||||
|
.pluginIcon(info.nightscout.core.ui.R.drawable.ic_eopatch2_128) // TODO
|
||||||
|
.pluginName(R.string.medtrum)
|
||||||
|
.shortName(R.string.medtrum_pump_shortname)
|
||||||
|
.preferencesId(R.xml.pref_medtrum_pump)
|
||||||
|
.description(R.string.medtrum_pump_description), injector, aapsLogger, rh, commandQueue
|
||||||
|
), Pump {
|
||||||
|
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
aapsLogger.debug(LTag.PUMP, "MedtrumPumpPlugin onStop()")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isInitialized(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSuspended(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isBusy(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isConnected(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isConnecting(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isHandshakeInProgress(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun finishHandshaking() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun connect(reason: String) {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Medtrum connect - reason:$reason")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun disconnect(reason: String) {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Medtrum disconnect - reason:$reason")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopConnecting() {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPumpStatus(reason: String) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isThisProfileSet(profile: Profile): Boolean {
|
||||||
|
return false // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun lastDataTime(): Long {
|
||||||
|
return 0 // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override val baseBasalRate: Double
|
||||||
|
get() = 0.0 // TODO
|
||||||
|
|
||||||
|
override val reservoirLevel: Double
|
||||||
|
get() = 0.0 // TODO
|
||||||
|
|
||||||
|
override val batteryLevel: Int
|
||||||
|
get() = 0 // TODO
|
||||||
|
|
||||||
|
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopBolusDelivering() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
||||||
|
aapsLogger.info(LTag.PUMP, "setTempBasalPercent - percent: $percent, durationInMinutes: $durationInMinutes, enforceNew: $enforceNew")
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult {
|
||||||
|
aapsLogger.info(LTag.PUMP, "setExtendedBolus - insulin: $insulin, durationInMinutes: $durationInMinutes")
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cancelExtendedBolus(): PumpEnactResult {
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject {
|
||||||
|
return JSONObject() // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun manufacturer(): ManufacturerType {
|
||||||
|
return ManufacturerType.Medtrum
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun model(): PumpType {
|
||||||
|
return PumpType.GENERIC_AAPS // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialNumber(): String {
|
||||||
|
return "0" // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override val pumpDescription: PumpDescription
|
||||||
|
get() = PumpDescription(PumpType.GENERIC_AAPS) // TODO
|
||||||
|
|
||||||
|
override fun shortStatus(veryShort: Boolean): String {
|
||||||
|
return ""// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isFakingTempsByExtendedBoluses: Boolean = false //TODO
|
||||||
|
|
||||||
|
override fun loadTDDs(): PumpEnactResult {
|
||||||
|
return PumpEnactResult(injector) // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canHandleDST(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCustomActions(): List<CustomAction>? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun executeCustomAction(customActionType: CustomActionType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun executeCustomCommand(customCommand: CustomCommand): PumpEnactResult? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readTBR(): PumpSync.PumpState.TemporaryBasal? {
|
||||||
|
return pumpSync.expectedPumpState().temporaryBasal // TODO
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package info.nightscout.pump.medtrum.di
|
||||||
|
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.android.ContributesAndroidInjector
|
||||||
|
import info.nightscout.pump.medtrum.ui.MedtrumPumpFragment
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@Suppress("unused")
|
||||||
|
abstract class MedtrumPumpModule {
|
||||||
|
|
||||||
|
@ContributesAndroidInjector abstract fun contributesMedtrumPumpFragment(): MedtrumPumpFragment
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package info.nightscout.pump.medtrum.events
|
||||||
|
|
||||||
|
import info.nightscout.rx.events.EventUpdateGui
|
||||||
|
|
||||||
|
class EventMedtrumPumpUpdateGui : EventUpdateGui()
|
|
@ -0,0 +1,103 @@
|
||||||
|
package info.nightscout.pump.medtrum.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.HandlerThread
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import dagger.android.support.DaggerFragment
|
||||||
|
import info.nightscout.core.extensions.toStringFull
|
||||||
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
|
import info.nightscout.pump.medtrum.databinding.MedtrumPumpFragmentBinding
|
||||||
|
import info.nightscout.pump.medtrum.events.EventMedtrumPumpUpdateGui
|
||||||
|
import info.nightscout.pump.medtrum.MedtrumPumpPlugin
|
||||||
|
import info.nightscout.rx.AapsSchedulers
|
||||||
|
import info.nightscout.rx.bus.RxBus
|
||||||
|
import info.nightscout.rx.events.EventExtendedBolusChange
|
||||||
|
import info.nightscout.rx.events.EventTempBasalChange
|
||||||
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
import info.nightscout.shared.utils.T
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class MedtrumPumpFragment : DaggerFragment() {
|
||||||
|
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||||
|
@Inject lateinit var medtrumPumpPlugin: MedtrumPumpPlugin
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||||
|
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
private lateinit var refreshLoop: Runnable
|
||||||
|
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||||
|
|
||||||
|
private var _binding: MedtrumPumpFragmentBinding? = null
|
||||||
|
|
||||||
|
// This property is only valid between onCreateView and
|
||||||
|
// onDestroyView.
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||||
|
MedtrumPumpFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventMedtrumPumpUpdateGui::class.java)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateGui() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventTempBasalChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateGui() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventExtendedBolusChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateGui() }, fabricPrivacy::logException)
|
||||||
|
refreshLoop = Runnable {
|
||||||
|
activity?.runOnUiThread { updateGui() }
|
||||||
|
handler.postDelayed(refreshLoop, T.mins(1).msecs())
|
||||||
|
}
|
||||||
|
handler.postDelayed(refreshLoop, T.mins(1).msecs())
|
||||||
|
updateGui()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
disposable.clear()
|
||||||
|
handler.removeCallbacksAndMessages(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun updateGui() {
|
||||||
|
if (_binding == null) return
|
||||||
|
val profile = profileFunction.getProfile() ?: return
|
||||||
|
binding.baseBasalRate.text = rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, medtrumPumpPlugin.baseBasalRate)
|
||||||
|
binding.tempbasal.text = iobCobCalculator.getTempBasal(dateUtil.now())?.toStringFull(profile, dateUtil)
|
||||||
|
?: ""
|
||||||
|
binding.extendedbolus.text = iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil)
|
||||||
|
?: ""
|
||||||
|
binding.battery.text = rh.gs(info.nightscout.core.ui.R.string.format_percent, 0) // TODO
|
||||||
|
binding.reservoir.text = rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, 0.0) // TODO
|
||||||
|
|
||||||
|
binding.serialNumber.text = medtrumPumpPlugin.serialNumber()
|
||||||
|
}
|
||||||
|
}
|
306
pump/medtrum/src/main/res/layout/medtrum_pump_fragment.xml
Normal file
306
pump/medtrum/src/main/res/layout/medtrum_pump_fragment.xml
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".MedtrumPumpFragment">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="@string/medtrum_pump_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:text="@string/base_basal_rate_label"
|
||||||
|
android:textAlignment="viewEnd"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text=":"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/base_basal_rate"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:text="0.38 U/h" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="2dip"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:background="?android:attr/dividerHorizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:text="@string/tempbasal_label"
|
||||||
|
android:textAlignment="viewEnd"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text=":"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tempbasal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="2dip"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:background="?android:attr/dividerHorizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:text="@string/extended_bolus_label"
|
||||||
|
android:textAlignment="viewEnd"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text=":"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/extendedbolus"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="2dip"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:background="?android:attr/dividerHorizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:text="@string/battery_label"
|
||||||
|
android:textAlignment="viewEnd"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text=":"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/battery"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:text="50%" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Reservoir -->
|
||||||
|
<View
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="2dip"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:background="?android:attr/dividerHorizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:text="@string/reservoir_label"
|
||||||
|
android:textAlignment="viewEnd"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text=":"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/reservoir"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Pump Serial -->
|
||||||
|
<View
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="2dip"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:background="?android:attr/dividerHorizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:text="@string/serial_number"
|
||||||
|
android:textAlignment="viewEnd"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text=":"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/serial_number"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
17
pump/medtrum/src/main/res/values/strings.xml
Normal file
17
pump/medtrum/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- MedtrumPump -->
|
||||||
|
<string name="key_snInput" translatable="false">snInput</string>
|
||||||
|
<string name="key_medtrumpump_settings" translatable="false">medtrumpump_settings</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="medtrum">Medtrum</string>
|
||||||
|
<string name="medtrum_pump_shortname">MEDTRUM</string>
|
||||||
|
<string name="medtrum_pump_description">Medtrum Nano</string>
|
||||||
|
<string name="medtrum_pump_label">MEDTRUM</string>
|
||||||
|
<string name="medtrumpump_settings">Medtrum pump settings</string>
|
||||||
|
|
||||||
|
<string name="snInput_title">SN</string>
|
||||||
|
<string name="snInput_summary">Serial number pump base</string>
|
||||||
|
|
||||||
|
</resources>
|
17
pump/medtrum/src/main/res/xml/pref_medtrum_pump.xml
Normal file
17
pump/medtrum/src/main/res/xml/pref_medtrum_pump.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="@string/key_medtrumpump_settings"
|
||||||
|
android:title="@string/medtrumpump_settings"
|
||||||
|
app:initialExpandedChildrenCount="0">
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="@string/key_snInput"
|
||||||
|
android:summary="@string/snInput_summary"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:title="@string/snInput_title" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
</androidx.preference.PreferenceScreen>
|
|
@ -0,0 +1,37 @@
|
||||||
|
package info.nightscout.androidaps
|
||||||
|
|
||||||
|
import info.nightscout.rx.AapsSchedulers
|
||||||
|
import info.nightscout.rx.TestAapsSchedulers
|
||||||
|
import info.nightscout.rx.logging.AAPSLoggerTest
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
import org.mockito.Mockito
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
|
import org.mockito.junit.jupiter.MockitoSettings
|
||||||
|
import org.mockito.quality.Strictness
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension::class)
|
||||||
|
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||||
|
open class TestBase {
|
||||||
|
|
||||||
|
val aapsLogger = AAPSLoggerTest()
|
||||||
|
val aapsSchedulers: AapsSchedulers = TestAapsSchedulers()
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setupLocale() {
|
||||||
|
Locale.setDefault(Locale.ENGLISH)
|
||||||
|
System.setProperty("disableFirebase", "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workaround for Kotlin nullability.
|
||||||
|
// https://medium.com/@elye.project/befriending-kotlin-and-mockito-1c2e7b0ef791
|
||||||
|
// https://stackoverflow.com/questions/30305217/is-it-possible-to-use-mockito-in-kotlin
|
||||||
|
fun <T> anyObject(): T {
|
||||||
|
Mockito.any<T>()
|
||||||
|
return uninitialized()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("Unchecked_Cast")
|
||||||
|
fun <T> uninitialized(): T = null as T
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ include ':pump:diaconn'
|
||||||
include ':pump:eopatch'
|
include ':pump:eopatch'
|
||||||
include ':pump:eopatch-core'
|
include ':pump:eopatch-core'
|
||||||
include ':insight'
|
include ':insight'
|
||||||
|
include ':pump:medtrum'
|
||||||
include ':pump:medtronic'
|
include ':pump:medtronic'
|
||||||
include ':pump:omnipod-common'
|
include ':pump:omnipod-common'
|
||||||
include ':pump:omnipod-eros'
|
include ':pump:omnipod-eros'
|
||||||
|
|
Loading…
Reference in a new issue