new plugin category: Smoothing

This commit is contained in:
Milos Kozak 2022-12-07 21:11:23 +01:00
parent ed6858bee7
commit 6d255032a8
21 changed files with 181 additions and 4 deletions

View file

@ -177,7 +177,6 @@ allprojects {
} }
dependencies { dependencies {
implementation project(path: ':plugins:aps')
wearApp project(':wear') wearApp project(':wear')
// in order to use internet's versions you'd need to enable Jetifier again // in order to use internet's versions you'd need to enable Jetifier again
@ -201,6 +200,7 @@ dependencies {
implementation project(':plugins:main') implementation project(':plugins:main')
implementation project(':plugins:openhumans') implementation project(':plugins:openhumans')
implementation project(':plugins:sensitivity') implementation project(':plugins:sensitivity')
implementation project(':plugins:smoothing')
implementation project(':plugins:support') implementation project(':plugins:support')
implementation project(':plugins:sync') implementation project(':plugins:sync')
implementation project(':implementation') implementation project(':implementation')

View file

@ -8,7 +8,6 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploaderPlugin import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploaderPlugin
import info.nightscout.plugins.general.persistentNotification.PersistentNotificationPlugin
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
@ -31,6 +30,7 @@ import info.nightscout.plugins.general.autotune.AutotunePlugin
import info.nightscout.plugins.general.dataBroadcaster.DataBroadcastPlugin import info.nightscout.plugins.general.dataBroadcaster.DataBroadcastPlugin
import info.nightscout.plugins.general.food.FoodPlugin import info.nightscout.plugins.general.food.FoodPlugin
import info.nightscout.plugins.general.overview.OverviewPlugin import info.nightscout.plugins.general.overview.OverviewPlugin
import info.nightscout.plugins.general.persistentNotification.PersistentNotificationPlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
import info.nightscout.plugins.general.wear.WearPlugin import info.nightscout.plugins.general.wear.WearPlugin
@ -62,6 +62,8 @@ import info.nightscout.pump.diaconn.DiaconnG8Plugin
import info.nightscout.sensitivity.SensitivityAAPSPlugin import info.nightscout.sensitivity.SensitivityAAPSPlugin
import info.nightscout.sensitivity.SensitivityOref1Plugin import info.nightscout.sensitivity.SensitivityOref1Plugin
import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
import info.nightscout.smoothing.ExponentialSmoothingPlugin
import info.nightscout.smoothing.NoSmoothingPlugin
import javax.inject.Qualifier import javax.inject.Qualifier
@Suppress("unused") @Suppress("unused")
@ -434,6 +436,18 @@ abstract class PluginsListModule {
@IntKey(500) @IntKey(500)
abstract fun bindThemeSwitcherPlugin(plugin: ThemeSwitcherPlugin): PluginBase abstract fun bindThemeSwitcherPlugin(plugin: ThemeSwitcherPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(600)
abstract fun bindNoSmoothingPlugin(plugin: NoSmoothingPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(605)
abstract fun bindExponentialSmoothingPlugin(plugin: ExponentialSmoothingPlugin): PluginBase
@Qualifier @Qualifier
annotation class AllConfigs annotation class AllConfigs

View file

@ -9,6 +9,7 @@ import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.profile.ProfileSource import info.nightscout.interfaces.profile.ProfileSource
import info.nightscout.interfaces.pump.Pump import info.nightscout.interfaces.pump.Pump
import info.nightscout.interfaces.smoothing.Smoothing
import info.nightscout.interfaces.source.BgSource import info.nightscout.interfaces.source.BgSource
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.sync.Sync
@ -74,6 +75,11 @@ interface ActivePlugin {
*/ */
val activeObjectives: Objectives? val activeObjectives: Objectives?
/**
* Smoothing plugin
*/
val activeSmoothing: Smoothing?
/** /**
* Currently selected NsClient plugin * Currently selected NsClient plugin
*/ */

View file

@ -6,5 +6,5 @@ package info.nightscout.interfaces.plugin
* set by [info.nightscout.interfaces.PluginDescription.mainType] * set by [info.nightscout.interfaces.PluginDescription.mainType]
*/ */
enum class PluginType { enum class PluginType {
GENERAL, SENSITIVITY, PROFILE, APS, PUMP, CONSTRAINTS, LOOP, BGSOURCE, INSULIN, SYNC GENERAL, SENSITIVITY, PROFILE, APS, PUMP, CONSTRAINTS, LOOP, BGSOURCE, INSULIN, SYNC, SMOOTHING
} }

View file

@ -0,0 +1,4 @@
package info.nightscout.interfaces.smoothing
interface Smoothing {
}

View file

@ -59,6 +59,7 @@ data class RemoteDeviceStatus(
@SerializedName("version") val version: String?, @SerializedName("version") val version: String?,
@SerializedName("insulin") val insulin: Int?, @SerializedName("insulin") val insulin: Int?,
@SerializedName("sensitivity") val sensitivity: Int?, @SerializedName("sensitivity") val sensitivity: Int?,
@SerializedName("smoothing") val smoothing: String?,
@Contextual @SerializedName("insulinConfiguration") val insulinConfiguration: JSONObject?, @Contextual @SerializedName("insulinConfiguration") val insulinConfiguration: JSONObject?,
@Contextual @SerializedName("sensitivityConfiguration") val sensitivityConfiguration: JSONObject?, @Contextual @SerializedName("sensitivityConfiguration") val sensitivityConfiguration: JSONObject?,
@Contextual @SerializedName("overviewConfiguration") val overviewConfiguration: JSONObject?, @Contextual @SerializedName("overviewConfiguration") val overviewConfiguration: JSONObject?,

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M23,8c0,1.1 -0.9,2 -2,2c-0.18,0 -0.35,-0.02 -0.51,-0.07l-3.56,3.55C16.98,13.64 17,13.82 17,14c0,1.1 -0.9,2 -2,2s-2,-0.9 -2,-2c0,-0.18 0.02,-0.36 0.07,-0.52l-2.55,-2.55C10.36,10.98 10.18,11 10,11s-0.36,-0.02 -0.52,-0.07l-4.55,4.56C4.98,15.65 5,15.82 5,16c0,1.1 -0.9,2 -2,2s-2,-0.9 -2,-2s0.9,-2 2,-2c0.18,0 0.35,0.02 0.51,0.07l4.56,-4.55C8.02,9.36 8,9.18 8,9c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,0.18 -0.02,0.36 -0.07,0.52l2.55,2.55C14.64,12.02 14.82,12 15,12s0.36,0.02 0.52,0.07l3.55,-3.56C19.02,8.35 19,8.18 19,8c0,-1.1 0.9,-2 2,-2S23,6.9 23,8z"/>
</vector>

View file

@ -14,6 +14,7 @@ import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.ProfileSource import info.nightscout.interfaces.profile.ProfileSource
import info.nightscout.interfaces.pump.Pump import info.nightscout.interfaces.pump.Pump
import info.nightscout.interfaces.smoothing.Smoothing
import info.nightscout.interfaces.source.BgSource import info.nightscout.interfaces.source.BgSource
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.sync.Sync
@ -191,6 +192,8 @@ class PluginStore @Inject constructor(
get() = getSpecificPluginsListByInterface(IobCobCalculator::class.java).first() as IobCobCalculator get() = getSpecificPluginsListByInterface(IobCobCalculator::class.java).first() as IobCobCalculator
override val activeObjectives: Objectives? override val activeObjectives: Objectives?
get() = getSpecificPluginsListByInterface(Objectives::class.java).firstOrNull() as Objectives get() = getSpecificPluginsListByInterface(Objectives::class.java).firstOrNull() as Objectives
override val activeSmoothing: Smoothing?
get() = getSpecificPluginsListByInterface(Smoothing::class.java).firstOrNull() as Smoothing
override val activeNsClient: NsClient? override val activeNsClient: NsClient?
get() = getTheOneEnabledInArray(getSpecificPluginsListByInterface(NsClient::class.java), PluginType.SYNC) as NsClient? get() = getTheOneEnabledInArray(getSpecificPluginsListByInterface(NsClient::class.java), PluginType.SYNC) as NsClient?

View file

@ -103,6 +103,7 @@ class ConfigBuilderFragment : DaggerFragment() {
createViewsForPlugins(info.nightscout.core.ui.R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, activePlugin.getSpecificPluginsVisibleInList(PluginType.INSULIN)) createViewsForPlugins(info.nightscout.core.ui.R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, activePlugin.getSpecificPluginsVisibleInList(PluginType.INSULIN))
if (!config.NSCLIENT) { if (!config.NSCLIENT) {
createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, activePlugin.getSpecificPluginsVisibleInList(PluginType.BGSOURCE)) createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, activePlugin.getSpecificPluginsVisibleInList(PluginType.BGSOURCE))
createViewsForPlugins(R.string.configbuilder_smoothing, R.string.configbuilder_smoothing_description, PluginType.SMOOTHING, activePlugin.getSpecificPluginsVisibleInList(PluginType.SMOOTHING))
createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, activePlugin.getSpecificPluginsVisibleInList(PluginType.PUMP)) createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, activePlugin.getSpecificPluginsVisibleInList(PluginType.PUMP))
} }
if (config.APS || config.PUMPCONTROL || config.isEngineeringMode()) if (config.APS || config.PUMPCONTROL || config.isEngineeringMode())

View file

@ -20,6 +20,7 @@ import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.ProfileSource import info.nightscout.interfaces.profile.ProfileSource
import info.nightscout.interfaces.pump.Pump import info.nightscout.interfaces.pump.Pump
import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.PumpSync
import info.nightscout.interfaces.smoothing.Smoothing
import info.nightscout.interfaces.source.BgSource import info.nightscout.interfaces.source.BgSource
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -131,7 +132,9 @@ class ConfigBuilderPlugin @Inject constructor(
(if (p.isEnabled(PluginType.CONSTRAINTS)) " CONSTRAINTS" else "") + (if (p.isEnabled(PluginType.CONSTRAINTS)) " CONSTRAINTS" else "") +
(if (p.isEnabled(PluginType.LOOP)) " LOOP" else "") + (if (p.isEnabled(PluginType.LOOP)) " LOOP" else "") +
(if (p.isEnabled(PluginType.BGSOURCE)) " BGSOURCE" else "") + (if (p.isEnabled(PluginType.BGSOURCE)) " BGSOURCE" else "") +
if (p.isEnabled(PluginType.INSULIN)) " INSULIN" else "" (if (p.isEnabled(PluginType.INSULIN)) " INSULIN" else "") +
(if (p.isEnabled(PluginType.SYNC)) " SYNC" else "") +
if (p.isEnabled(PluginType.SMOOTHING)) " SMOOTHING" else ""
) )
} }
} }
@ -195,6 +198,7 @@ class ConfigBuilderPlugin @Inject constructor(
when (type) { when (type) {
PluginType.INSULIN -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(Insulin::class.java) PluginType.INSULIN -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(Insulin::class.java)
PluginType.SENSITIVITY -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(Sensitivity::class.java) PluginType.SENSITIVITY -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(Sensitivity::class.java)
PluginType.SMOOTHING -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(Smoothing::class.java)
PluginType.APS -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(APS::class.java) PluginType.APS -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(APS::class.java)
PluginType.PROFILE -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(ProfileSource::class.java) PluginType.PROFILE -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(ProfileSource::class.java)
PluginType.BGSOURCE -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(BgSource::class.java) PluginType.BGSOURCE -> pluginsInCategory = activePlugin.getSpecificPluginsListByInterface(BgSource::class.java)

View file

@ -11,6 +11,7 @@ import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.PumpSync
import info.nightscout.interfaces.pump.defs.PumpType import info.nightscout.interfaces.pump.defs.PumpType
import info.nightscout.interfaces.smoothing.Smoothing
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog import info.nightscout.rx.events.EventNSClientNewLog
@ -52,11 +53,13 @@ class RunningConfigurationImpl @Inject constructor(
val sensitivityInterface = activePlugin.activeSensitivity val sensitivityInterface = activePlugin.activeSensitivity
val overviewInterface = activePlugin.activeOverview val overviewInterface = activePlugin.activeOverview
val safetyInterface = activePlugin.activeSafety val safetyInterface = activePlugin.activeSafety
val smoothingInterface = activePlugin.activeSmoothing
json.put("insulin", insulinInterface.id.value) json.put("insulin", insulinInterface.id.value)
json.put("insulinConfiguration", insulinInterface.configuration()) json.put("insulinConfiguration", insulinInterface.configuration())
json.put("sensitivity", sensitivityInterface.id.value) json.put("sensitivity", sensitivityInterface.id.value)
json.put("sensitivityConfiguration", sensitivityInterface.configuration()) json.put("sensitivityConfiguration", sensitivityInterface.configuration())
json.put("smoothing", smoothingInterface?.javaClass?.simpleName)
json.put("overviewConfiguration", overviewInterface.configuration()) json.put("overviewConfiguration", overviewInterface.configuration())
json.put("safetyConfiguration", safetyInterface.configuration()) json.put("safetyConfiguration", safetyInterface.configuration())
json.put("pump", pumpInterface.model().description) json.put("pump", pumpInterface.model().description)
@ -104,6 +107,18 @@ class RunningConfigurationImpl @Inject constructor(
} }
} }
configuration.smoothing?.let {
for (p in activePlugin.getSpecificPluginsListByInterface(Smoothing::class.java)) {
val smoothingPlugin = p as Smoothing
if (smoothingPlugin.javaClass.simpleName == it) {
if (!p.isEnabled()) {
aapsLogger.debug(LTag.CORE, "Changing smoothing plugin to ${smoothingPlugin.javaClass.simpleName}")
configBuilder.performPluginSwitch(p, true, PluginType.SMOOTHING)
}
}
}
}
configuration.pump?.let { configuration.pump?.let {
if (sp.getString(info.nightscout.core.utils.R.string.key_virtualpump_type, "fake") != it) { if (sp.getString(info.nightscout.core.utils.R.string.key_virtualpump_type, "fake") != it) {
sp.putString(info.nightscout.core.utils.R.string.key_virtualpump_type, it) sp.putString(info.nightscout.core.utils.R.string.key_virtualpump_type, it)

View file

@ -77,6 +77,8 @@
<string name="configbuilder_insulin_description">Which type of insulin are you using?</string> <string name="configbuilder_insulin_description">Which type of insulin are you using?</string>
<string name="configbuilder_bgsource">BG Source</string> <string name="configbuilder_bgsource">BG Source</string>
<string name="configbuilder_bgsource_description">Where should AAPS gain it\'s data from?</string> <string name="configbuilder_bgsource_description">Where should AAPS gain it\'s data from?</string>
<string name="configbuilder_smoothing">Smoothing</string>
<string name="configbuilder_smoothing_description">Choose smoothing algorithm</string>
<string name="configbuilder_sensitivity">Sensitivity detection</string> <string name="configbuilder_sensitivity">Sensitivity detection</string>
<string name="configbuilder_sensitivity_description">Which sensitivity algorithm should be used?</string> <string name="configbuilder_sensitivity_description">Which sensitivity algorithm should be used?</string>
<string name="config_builder_shortname">CONF</string> <string name="config_builder_shortname">CONF</string>

1
plugins/smoothing/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,24 @@
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.smoothing'
}
dependencies {
implementation project(':app-wear-shared:shared')
implementation project(':database:entities')
implementation project(':core:interfaces')
implementation project(':core:ui')
}

View file

21
plugins/smoothing/proguard-rules.pro vendored Normal file
View 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

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View file

@ -0,0 +1,31 @@
package info.nightscout.smoothing
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.smoothing.Smoothing
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
@OpenForTesting
@Singleton
class ExponentialSmoothingPlugin @Inject constructor(
injector: HasAndroidInjector,
aapsLogger: AAPSLogger,
rh: ResourceHelper,
activePlugin: ActivePlugin,
) : PluginBase(
PluginDescription()
.mainType(PluginType.SMOOTHING)
.pluginIcon(info.nightscout.core.ui.R.drawable.ic_timeline_24)
.pluginName(R.string.exponential_smoothing_name)
.shortName(R.string.smoothing_shortname)
.description(R.string.description_exponential_smoothing),
aapsLogger, rh, injector
), Smoothing {
}

View file

@ -0,0 +1,31 @@
package info.nightscout.smoothing
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.smoothing.Smoothing
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
@OpenForTesting
@Singleton
class NoSmoothingPlugin @Inject constructor(
injector: HasAndroidInjector,
aapsLogger: AAPSLogger,
rh: ResourceHelper
) : PluginBase(
PluginDescription()
.mainType(PluginType.SMOOTHING)
.pluginIcon(info.nightscout.core.ui.R.drawable.ic_timeline_24)
.enableByDefault(true)
.pluginName(R.string.no_smoothing_name)
.shortName(R.string.smoothing_shortname)
.description(R.string.description_no_smoothing),
aapsLogger, rh, injector
), Smoothing {
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="smoothing_shortname">SMOOTH</string>
<string name="exponential_smoothing_name">Exponential smoothing</string>
<string name="description_exponential_smoothing">"Second-order exponential smoothing algorithm"</string>
<string name="no_smoothing_name">No smoothing</string>
<string name="description_no_smoothing">"No smoothing performed on input glucose data"</string>
</resources>

View file

@ -21,6 +21,7 @@ include ':plugins:configuration'
include ':plugins:main' include ':plugins:main'
include ':plugins:openhumans' include ':plugins:openhumans'
include ':plugins:sensitivity' include ':plugins:sensitivity'
include ':plugins:smoothing'
include ':plugins:support' include ':plugins:support'
include ':pump:combo' include ':pump:combo'
include ':pump:combov2' include ':pump:combov2'