Merge branch 'dev' into smoothing

This commit is contained in:
Milos Kozak 2022-12-09 17:16:53 +01:00
commit 41f0f8a4ce
337 changed files with 1332 additions and 1048 deletions

View file

@ -197,11 +197,13 @@ dependencies {
implementation project(':plugins:aps')
implementation project(':plugins:automation')
implementation project(':plugins:configuration')
implementation project(':plugins:constraints')
implementation project(':plugins:insulin')
implementation project(':plugins:main')
implementation project(':plugins:openhumans')
implementation project(':plugins:sensitivity')
implementation project(':plugins:smoothing')
implementation project(':plugins:support')
implementation project(':plugins:source')
implementation project(':plugins:sync')
implementation project(':implementation')
implementation project(':database:entities')
@ -217,10 +219,11 @@ dependencies {
implementation project(':pump:medtronic')
implementation project(':pump:pump-common')
implementation project(':pump:pump-core')
implementation project(':pump:rileylink')
implementation project(':pump:omnipod-common')
implementation project(':pump:omnipod-eros')
implementation project(':pump:omnipod-dash')
implementation project(':pump:rileylink')
implementation project(':pump:virtual')
implementation project(':workflow')
implementation fileTree(include: ['*.jar'], dir: 'libs')

View file

@ -132,7 +132,7 @@
</provider>
<service
android:name="info.nightscout.core.services.AlarmSoundService"
android:name="info.nightscout.ui.services.AlarmSoundService"
android:enabled="true"
android:exported="true" />
<uses-library

View file

@ -28,6 +28,7 @@ import info.nightscout.automation.AutomationPlugin
import info.nightscout.configuration.maintenance.MaintenancePlugin
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.implementation.plugin.PluginStore
import info.nightscout.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.plugin.PluginBase
@ -47,22 +48,13 @@ import info.nightscout.plugins.general.autotune.AutotunePlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.plugins.source.AidexPlugin
import info.nightscout.plugins.source.DexcomPlugin
import info.nightscout.plugins.source.EversensePlugin
import info.nightscout.plugins.source.GlimpPlugin
import info.nightscout.plugins.source.GlunovoPlugin
import info.nightscout.plugins.source.IntelligoPlugin
import info.nightscout.plugins.source.PoctechPlugin
import info.nightscout.plugins.source.TomatoPlugin
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
import info.nightscout.pump.combo.ComboPlugin
import info.nightscout.pump.combov2.ComboV2Plugin
import info.nightscout.pump.diaconn.DiaconnG8Plugin
import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventRebuildTabs
@ -72,6 +64,14 @@ import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.source.AidexPlugin
import info.nightscout.source.DexcomPlugin
import info.nightscout.source.EversensePlugin
import info.nightscout.source.GlimpPlugin
import info.nightscout.source.GlunovoPlugin
import info.nightscout.source.IntelligoPlugin
import info.nightscout.source.PoctechPlugin
import info.nightscout.source.TomatoPlugin
import javax.inject.Inject
class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListener {

View file

@ -20,9 +20,10 @@ import info.nightscout.core.di.CoreModule
import info.nightscout.core.validators.di.ValidatorsModule
import info.nightscout.database.impl.DatabaseModule
import info.nightscout.implementation.di.ImplementationModule
import info.nightscout.insulin.di.InsulinModule
import info.nightscout.plugins.aps.di.ApsModule
import info.nightscout.plugins.constraints.di.PluginsConstraintsModule
import info.nightscout.plugins.di.PluginsModule
import info.nightscout.plugins.support.di.PluginsSupportModule
import info.nightscout.plugins.sync.di.SyncModule
import info.nightscout.pump.combo.di.ComboModule
import info.nightscout.pump.combov2.di.ComboV2Module
@ -31,9 +32,11 @@ import info.nightscout.pump.dana.di.DanaHistoryModule
import info.nightscout.pump.dana.di.DanaModule
import info.nightscout.pump.danars.di.DanaRSModule
import info.nightscout.pump.diaconn.di.DiaconnG8Module
import info.nightscout.pump.virtual.di.VirtualPumpModule
import info.nightscout.rx.di.RxModule
import info.nightscout.shared.di.SharedModule
import info.nightscout.shared.impl.di.SharedImplModule
import info.nightscout.source.di.SourceModule
import info.nightscout.ui.di.UiModule
import info.nightscout.workflow.di.WorkflowModule
import javax.inject.Singleton
@ -55,6 +58,7 @@ import javax.inject.Singleton
CoreModule::class,
DatabaseModule::class,
ImplementationModule::class,
InsulinModule::class,
OpenHumansModule::class,
PluginsModule::class,
RxModule::class,
@ -62,7 +66,8 @@ import javax.inject.Singleton
SharedImplModule::class,
UiModule::class,
ValidatorsModule::class,
PluginsSupportModule::class,
PluginsConstraintsModule::class,
SourceModule::class,
SyncModule::class,
WorkflowModule::class,
@ -81,7 +86,8 @@ import javax.inject.Singleton
OmnipodDashModule::class,
OmnipodErosModule::class,
PumpCommonModule::class,
RileyLinkModule::class
RileyLinkModule::class,
VirtualPumpModule::class
]
)
interface AppComponent : AndroidInjector<MainApp> {

View file

@ -7,13 +7,15 @@ import dagger.Module
import dagger.Provides
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.implementations.UiInteractionImpl
import info.nightscout.androidaps.implementations.ConfigImpl
import info.nightscout.androidaps.implementations.InstantiatorImpl
import info.nightscout.androidaps.implementations.UiInteractionImpl
import info.nightscout.androidaps.workflow.CalculationWorkflowImpl
import info.nightscout.androidaps.workflow.WorkerClassesImpl
import info.nightscout.core.workflow.CalculationWorkflow
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.workflow.WorkerClasses
@ -53,6 +55,8 @@ open class AppModule {
@Binds fun bindActivityNames(activityNames: UiInteractionImpl): UiInteraction
@Binds fun bindWorkerClasses(workerClassesImpl: WorkerClassesImpl): WorkerClasses
@Binds fun bindCalculationWorkflow(calculationWorkflow: CalculationWorkflowImpl): CalculationWorkflow
@Binds fun bindInstantiator(instantiatorImpl: InstantiatorImpl): Instantiator
}
}

View file

@ -16,6 +16,10 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugi
import info.nightscout.automation.AutomationPlugin
import info.nightscout.configuration.configBuilder.ConfigBuilderPlugin
import info.nightscout.configuration.maintenance.MaintenancePlugin
import info.nightscout.insulin.InsulinLyumjevPlugin
import info.nightscout.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.insulin.InsulinOrefRapidActingPlugin
import info.nightscout.insulin.InsulinOrefUltraRapidActingPlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.plugins.aps.loop.LoopPlugin
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
@ -35,35 +39,31 @@ import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
import info.nightscout.plugins.insulin.InsulinLyumjevPlugin
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.plugins.insulin.InsulinOrefRapidActingPlugin
import info.nightscout.plugins.insulin.InsulinOrefUltraRapidActingPlugin
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.plugins.source.AidexPlugin
import info.nightscout.plugins.source.DexcomPlugin
import info.nightscout.plugins.source.GlimpPlugin
import info.nightscout.plugins.source.GlunovoPlugin
import info.nightscout.plugins.source.IntelligoPlugin
import info.nightscout.plugins.source.MM640gPlugin
import info.nightscout.plugins.source.NSClientSourcePlugin
import info.nightscout.plugins.source.PoctechPlugin
import info.nightscout.plugins.source.RandomBgPlugin
import info.nightscout.plugins.source.TomatoPlugin
import info.nightscout.plugins.source.XdripPlugin
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
import info.nightscout.pump.combo.ComboPlugin
import info.nightscout.pump.combov2.ComboV2Plugin
import info.nightscout.pump.diaconn.DiaconnG8Plugin
import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.sensitivity.SensitivityAAPSPlugin
import info.nightscout.sensitivity.SensitivityOref1Plugin
import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
import info.nightscout.smoothing.ExponentialSmoothingPlugin
import info.nightscout.smoothing.NoSmoothingPlugin
import info.nightscout.source.AidexPlugin
import info.nightscout.source.DexcomPlugin
import info.nightscout.source.GlimpPlugin
import info.nightscout.source.GlunovoPlugin
import info.nightscout.source.IntelligoPlugin
import info.nightscout.source.MM640gPlugin
import info.nightscout.source.NSClientSourcePlugin
import info.nightscout.source.PoctechPlugin
import info.nightscout.source.RandomBgPlugin
import info.nightscout.source.TomatoPlugin
import info.nightscout.source.XdripPlugin
import javax.inject.Qualifier
@Suppress("unused")

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.implementations
import dagger.Reusable
import dagger.android.HasAndroidInjector
import info.nightscout.implementation.profile.ProfileStoreObject
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.aps.AutosensData
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
import info.nightscout.shared.utils.DateUtil
import org.json.JSONObject
import javax.inject.Inject
@Reusable
class InstantiatorImpl @Inject constructor(
private val injector: HasAndroidInjector,
private val dateUtil: DateUtil
) : Instantiator {
override fun provideProfileStore(jsonObject: JSONObject): ProfileStore =
ProfileStoreObject(injector, jsonObject, dateUtil)
override fun provideAPSResultObject(): APSResult = APSResultObject(injector)
override fun provideAutosensDataObject(): AutosensData = AutosensDataObject(injector)
}

View file

@ -14,8 +14,8 @@ import info.nightscout.androidaps.activities.MyPreferenceFragment
import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.configuration.activities.SingleFragmentActivity
import info.nightscout.core.events.EventNewNotification
import info.nightscout.core.services.AlarmSoundService
import info.nightscout.core.services.AlarmSoundServiceHelper
import info.nightscout.ui.services.AlarmSoundService
import info.nightscout.ui.services.AlarmSoundServiceHelper
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.interfaces.notifications.Notification
import info.nightscout.interfaces.nsclient.NSAlarm
@ -39,6 +39,7 @@ import info.nightscout.ui.dialogs.TempBasalDialog
import info.nightscout.ui.dialogs.TempTargetDialog
import info.nightscout.ui.dialogs.TreatmentDialog
import info.nightscout.ui.dialogs.WizardDialog
import info.nightscout.ui.widget.Widget
import javax.inject.Inject
class UiInteractionImpl @Inject constructor(
@ -67,6 +68,10 @@ class UiInteractionImpl @Inject constructor(
context.startActivity(i)
}
override fun updateWidget(context: Context) {
Widget.updateWidget(context)
}
override fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int?, name: String?) {
WizardDialog().also { dialog ->
dialog.arguments = Bundle().also { bundle ->

View file

@ -12,17 +12,17 @@ import info.nightscout.core.utils.extensions.copyString
import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.interfaces.receivers.Intents
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.source.AidexPlugin
import info.nightscout.plugins.source.DexcomPlugin
import info.nightscout.plugins.source.EversensePlugin
import info.nightscout.plugins.source.GlimpPlugin
import info.nightscout.plugins.source.MM640gPlugin
import info.nightscout.plugins.source.PoctechPlugin
import info.nightscout.plugins.source.TomatoPlugin
import info.nightscout.plugins.source.XdripPlugin
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.BundleLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.source.AidexPlugin
import info.nightscout.source.DexcomPlugin
import info.nightscout.source.EversensePlugin
import info.nightscout.source.GlimpPlugin
import info.nightscout.source.MM640gPlugin
import info.nightscout.source.PoctechPlugin
import info.nightscout.source.TomatoPlugin
import info.nightscout.source.XdripPlugin
import javax.inject.Inject
open class DataReceiver : DaggerBroadcastReceiver() {

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.workflow
import info.nightscout.interfaces.workflow.WorkerClasses
import info.nightscout.plugins.general.food.FoodPlugin
import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.plugins.source.NSClientSourcePlugin
import info.nightscout.source.NSClientSourcePlugin
import javax.inject.Inject
class WorkerClassesImpl @Inject constructor(): WorkerClasses{

View file

@ -79,7 +79,6 @@
<string name="authorizationfailed">Authorization failed</string>
<string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="time_to_eat">Time to eat!\nRun Bolus wizard and do calculation again.</string>
<string name="fabric_upload_disabled">Crash logs upload disabled!</string>
<string name="clear_filter">Clear filter</string>
<string name="cannula">Cannula</string>

View file

@ -11,7 +11,6 @@ import info.nightscout.androidaps.insight.database.InsightDatabaseDao
import info.nightscout.androidaps.insight.database.InsightDbHelper
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.database.impl.AppRepository
import info.nightscout.implementation.constraints.ConstraintsImpl
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraint
@ -21,7 +20,7 @@ import info.nightscout.interfaces.maintenance.PrefFileListProvider
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.ProfileInstantiator
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profiling.Profiler
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
import info.nightscout.interfaces.pump.PumpEnactResult
@ -34,17 +33,18 @@ import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
import info.nightscout.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.plugins.aps.openAPSSMBDynamicISF.OpenAPSSMBDynamicISFPlugin
import info.nightscout.plugins.constraints.ConstraintsImpl
import info.nightscout.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.plugins.constraints.objectives.objectives.Objective
import info.nightscout.plugins.constraints.safety.SafetyPlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.plugins.source.GlimpPlugin
import info.nightscout.pump.combo.ComboPlugin
import info.nightscout.pump.combo.ruffyscripter.RuffyScripter
import info.nightscout.pump.dana.DanaPump
import info.nightscout.pump.dana.R
import info.nightscout.pump.dana.database.DanaHistoryDatabase
import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.source.GlimpPlugin
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@ -70,7 +70,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
@Mock lateinit var insightDatabaseDao: InsightDatabaseDao
@Mock lateinit var ruffyScripter: RuffyScripter
@Mock lateinit var uiInteraction: UiInteraction
@Mock lateinit var profileInstantiator: ProfileInstantiator
@Mock lateinit var instantiator: Instantiator
@Mock lateinit var danaHistoryDatabase: DanaHistoryDatabase
@Mock lateinit var insightDatabase: InsightDatabase
@Mock lateinit var bgQualityCheck: BgQualityCheck
@ -103,33 +103,33 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
@BeforeEach
fun prepare() {
`when`(rh.gs(info.nightscout.plugins.R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
`when`(rh.gs(info.nightscout.plugins.R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
`when`(rh.gs(info.nightscout.core.ui.R.string.no_valid_basal_rate)).thenReturn("No valid basal rate read from pump")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.autosens_disabled_in_preferences)).thenReturn("Autosens disabled in preferences")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.smb_disabled_in_preferences)).thenReturn("SMB disabled in preferences")
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
`when`(rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)).thenReturn("it must be positive value")
`when`(rh.gs(info.nightscout.plugins.R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_basal_multiplier)).thenReturn("max basal multiplier")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_daily_basal_multiplier)).thenReturn("max daily basal multiplier")
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbolus)).thenReturn("Limiting bolus to %.1f U because of %s")
`when`(rh.gs(info.nightscout.plugins.R.string.hardlimit)).thenReturn("hard limit")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.hardlimit)).thenReturn("hard limit")
`when`(rh.gs(info.nightscout.core.utils.R.string.key_child)).thenReturn("child")
`when`(rh.gs(info.nightscout.plugins.R.string.limitingcarbs)).thenReturn("Limiting carbs to %d g because of %s")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.limitingcarbs)).thenReturn("Limiting carbs to %d g because of %s")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.limiting_iob)).thenReturn("Limiting IOB to %.1f U because of %s")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
`when`(rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)).thenReturn("it must be positive value")
`when`(rh.gs(info.nightscout.plugins.R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
`when`(rh.gs(info.nightscout.plugins.R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbolus)).thenReturn("Limiting bolus to %1\$.1f U because of %2\$s")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
`when`(context.getString(info.nightscout.pump.combo.R.string.combo_pump_unsupported_operation)).thenReturn("Requested operation not supported by pump")
`when`(rh.gs(info.nightscout.plugins.R.string.objectivenotstarted)).thenReturn("Objective %1\$d not started")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.objectivenotstarted)).thenReturn("Objective %1\$d not started")
// RS constructor
`when`(sp.getString(R.string.key_danars_name, "")).thenReturn("")
@ -145,7 +145,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
hardLimits = HardLimitsMock(sp, rh)
insightDbHelper = InsightDbHelper(insightDatabaseDao)
danaPump = DanaPump(aapsLogger, sp, dateUtil, profileInstantiator)
danaPump = DanaPump(aapsLogger, sp, dateUtil, instantiator)
objectivesPlugin = ObjectivesPlugin(injector, aapsLogger, rh, activePlugin, sp, config)
comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, rh, profileFunction, sp, commandQueue, pumpSync, dateUtil, ruffyScripter, uiInteraction)
danaRPlugin = DanaRPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, rh, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy, pumpSync,
@ -242,7 +242,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
hardLimits,
ConfigImpl(fileListProvider),
iobCobCalculator,
dateUtil
dateUtil,
uiInteraction
)
val constraintsPluginsList = ArrayList<PluginBase>()
constraintsPluginsList.add(safetyPlugin)

View file

@ -21,7 +21,7 @@ import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.plugins.aps.loop.LoopFragment
import info.nightscout.plugins.aps.loop.LoopPlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP

View file

@ -14,14 +14,14 @@ import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profiling.Profiler
import info.nightscout.interfaces.pump.defs.PumpDescription
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
import info.nightscout.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.plugins.constraints.safety.SafetyPlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.plugins.source.GlimpPlugin
import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.source.GlimpPlugin
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@ -39,6 +39,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
@Mock lateinit var repository: AppRepository
@Mock lateinit var glucoseStatusProvider: GlucoseStatusProvider
@Mock lateinit var bgQualityCheck: BgQualityCheck
@Mock lateinit var uiInteraction: UiInteraction
private lateinit var hardLimits: HardLimits
private lateinit var safetyPlugin: SafetyPlugin
@ -50,24 +51,24 @@ class SafetyPluginTest : TestBaseWithProfile() {
@BeforeEach
fun prepare() {
`when`(rh.gs(R.string.hardlimit)).thenReturn("hard limit")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.hardlimit)).thenReturn("hard limit")
`when`(rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)).thenReturn("it must be positive value")
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
`when`(rh.gs(R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_daily_basal_multiplier)).thenReturn("max daily basal multiplier")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_basal_multiplier)).thenReturn("max basal multiplier")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbolus)).thenReturn("Limiting bolus to %1\$.1f U because of %2\$s")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
`when`(rh.gs(info.nightscout.core.ui.R.string.limiting_iob)).thenReturn("Limiting IOB to %1\$.1f U because of %2\$s")
`when`(rh.gs(R.string.limitingcarbs)).thenReturn("Limiting carbs to %1\$d g because of %2\$s")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.limitingcarbs)).thenReturn("Limiting carbs to %1\$d g because of %2\$s")
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
`when`(rh.gs(R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.increasing_max_basal)).thenReturn("Increasing max basal value because setting is lower than your max basal in profile")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.smb_disabled_in_preferences)).thenReturn("SMB disabled in preferences")
`when`(rh.gs(R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
`when`(rh.gs(R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
`when`(rh.gs(R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
`when`(rh.gs(R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
`when`(rh.gs(info.nightscout.core.utils.R.string.key_child)).thenReturn("child")
`when`(rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)).thenReturn("Low Glucose Suspend")
@ -75,7 +76,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
`when`(config.APS).thenReturn(true)
hardLimits = HardLimitsMock(sp, rh)
safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, rxBus, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil)
safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, rxBus, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil, uiInteraction)
openAPSAMAPlugin = OpenAPSAMAPlugin(
injector, aapsLogger, rxBus, constraintChecker, rh, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, fabricPrivacy,
dateUtil, repository, glucoseStatusProvider, sp

View file

@ -6,7 +6,7 @@ import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.core.pump.toHtml
import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.plugins.aps.loop.extensions.json
import info.nightscout.plugins.extensions.toText
import info.nightscout.pump.virtual.extensions.toText
import info.nightscout.plugins.sync.nsShared.extensions.log
import org.json.JSONObject
import org.junit.jupiter.api.Assertions

View file

@ -1,4 +1,4 @@
package info.nightscout.plugins.insulin
package info.nightscout.core.graph
import android.content.Context
import android.graphics.Color

View file

@ -1,14 +0,0 @@
package info.nightscout.interfaces
interface BolusTimer {
/**
* Create new Automation event to alarm when is time to bolus
*/
fun scheduleAutomationEventBolusReminder()
/**
* Remove Automation event
*/
fun removeAutomationEventBolusReminder()
}

View file

@ -1,21 +0,0 @@
package info.nightscout.interfaces
interface CarbTimer {
/**
* Generate reminder via [info.nightscout.androidaps.utils.TimerUtil]
*
* @param seconds seconds to the future
*/
fun scheduleTimeToEatReminder(seconds: Int)
/**
* Create new Automation event to alarm when is time to eat
*/
fun scheduleAutomationEventEatReminder()
/**
* Remove Automation event
*/
fun removeAutomationEventEatReminder()
}

View file

@ -0,0 +1,3 @@
package info.nightscout.interfaces.actions
interface Actions

View file

@ -8,6 +8,7 @@ import info.nightscout.interfaces.iob.IobTotal
import org.json.JSONObject
interface APSResult {
var date: Long
var json: JSONObject?
var reason: String
var rate: Double

View file

@ -18,8 +18,13 @@ interface AutosensData {
var pastSensitivity: String
var deviation: Double
var validDeviation: Boolean
var activeCarbsList: MutableList<CarbsInPast>
var absorbed: Double
var carbsFromBolus: Double
var cob: Double
var bgi: Double
var delta: Double
var avgDelta: Double
var slopeFromMaxDeviation: Double
var slopeFromMinDeviation: Double
var usedMinCarbsImpact: Double
@ -37,4 +42,6 @@ interface AutosensData {
var autosensResult: AutosensResult
fun cloneCarbsList(): MutableList<CarbsInPast>
fun deductAbsorbedCarbs()
fun removeOldCarbs(toTime: Long, isAAPSOrWeighted: Boolean)
}

View file

@ -1,6 +1,36 @@
package info.nightscout.interfaces.automation
interface Automation {
fun userEvents(): List<AutomationEvent>
fun processEvent(someEvent: AutomationEvent)
/**
* Generate reminder via [info.nightscout.interfaces.utils.TimerUtil]
*
*/
fun scheduleAutomationEventBolusReminder()
/**
* Remove scheduled reminder from automations
*
*/
fun removeAutomationEventBolusReminder()
/**
* Generate reminder via [info.nightscout.interfaces.utils.TimerUtil]
*
* @param seconds seconds to the future
*/
fun scheduleTimeToEatReminder(seconds: Int)
/**
* Remove Automation event
*/
fun removeAutomationEventEatReminder()
/**
* Create new Automation event to alarm when is time to eat
*/
fun scheduleAutomationEventEatReminder()
}

View file

@ -5,6 +5,7 @@ import info.nightscout.database.ValueWrapper
import info.nightscout.database.entities.Bolus
import info.nightscout.database.entities.BolusCalculatorResult
import info.nightscout.database.entities.Carbs
import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.database.entities.UserEntry
import info.nightscout.interfaces.queue.Callback
@ -20,4 +21,5 @@ interface PersistenceLayer {
fun getTemporaryTargetActiveAt(timestamp: Long): Single<ValueWrapper<TemporaryTarget>>
fun getUserEntryFilteredDataFromTime(timestamp: Long): Single<List<UserEntry>>
fun getEffectiveProfileSwitchActiveAt(timestamp: Long): Single<ValueWrapper<EffectiveProfileSwitch>>
}

View file

@ -0,0 +1,12 @@
package info.nightscout.interfaces.profile
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.aps.AutosensData
import org.json.JSONObject
interface Instantiator {
fun provideProfileStore(jsonObject: JSONObject): ProfileStore
fun provideAPSResultObject(): APSResult
fun provideAutosensDataObject(): AutosensData
}

View file

@ -1,7 +0,0 @@
package info.nightscout.interfaces.profile
import org.json.JSONObject
interface ProfileInstantiator {
fun storeInstance(jsonObject: JSONObject): ProfileStore
}

View file

@ -1,3 +1,8 @@
package info.nightscout.interfaces.source
interface DexcomBoyda
interface DexcomBoyda {
fun isEnabled(): Boolean
fun requestPermissionIfNeeded()
fun findDexcomPackageName(): String?
}

View file

@ -0,0 +1,5 @@
package info.nightscout.interfaces.source
interface XDrip {
fun isEnabled(): Boolean
}

View file

@ -31,6 +31,9 @@ interface UiInteraction {
* @param soundId sound resource. if == 0 alarm is not started
*/
fun runAlarm(status: String, title: String, @RawRes soundId: Int = 0)
fun updateWidget(context: Context)
fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int? = null, name: String? = null)
fun runLoopDialog(fragmentManager: FragmentManager, showOkCancel: Int)
fun runProfileSwitchDialog(fragmentManager: FragmentManager, profileName: String? = null)

View file

@ -2,8 +2,6 @@ package info.nightscout.core.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.core.aps.APSResultObject
import info.nightscout.core.iob.iobCobCalculator.data.AutosensDataObject
import info.nightscout.core.wizard.BolusWizard
import info.nightscout.core.wizard.QuickWizardEntry
import info.nightscout.interfaces.pump.PumpEnactResult
@ -13,8 +11,6 @@ import info.nightscout.interfaces.pump.PumpEnactResult
abstract class CoreDataClassesModule {
@ContributesAndroidInjector abstract fun pumpEnactResultInjector(): PumpEnactResult
@ContributesAndroidInjector abstract fun apsResultInjector(): APSResultObject
@ContributesAndroidInjector abstract fun autosensDataInjector(): AutosensDataObject
@ContributesAndroidInjector abstract fun bolusWizardInjector(): BolusWizard
@ContributesAndroidInjector abstract fun quickWizardEntryInjector(): QuickWizardEntry
}

View file

@ -5,14 +5,11 @@ import android.os.Build
import android.telephony.SmsManager
import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector
import info.nightscout.core.services.AlarmSoundService
@Module(
includes = [
CoreDataClassesModule::class,
PreferencesModule::class,
ServicesModule::class
PreferencesModule::class
]
)
open class CoreModule {

View file

@ -1,12 +0,0 @@
package info.nightscout.core.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.core.services.AlarmSoundService
@Module
@Suppress("unused")
abstract class ServicesModule {
@ContributesAndroidInjector abstract fun contributesAlarmSoundService(): AlarmSoundService
}

View file

@ -1,2 +0,0 @@
package info.nightscout.core.profile

View file

@ -15,10 +15,9 @@ import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.database.entities.UserEntry.Action
import info.nightscout.database.entities.UserEntry.Sources
import info.nightscout.database.entities.ValueWithUnit
import info.nightscout.interfaces.BolusTimer
import info.nightscout.interfaces.CarbTimer
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.automation.Automation
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.db.PersistenceLayer
@ -69,8 +68,7 @@ class BolusWizard @Inject constructor(
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: Config
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var carbTimer: CarbTimer
@Inject lateinit var bolusTimer: BolusTimer
@Inject lateinit var automation: Automation
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
@Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var persistenceLayer: PersistenceLayer
@ -361,9 +359,9 @@ class BolusWizard @Inject constructor(
}
accepted = true
if (calculatedTotalInsulin > 0.0)
bolusTimer.removeAutomationEventBolusReminder()
automation.removeAutomationEventBolusReminder()
if (carbs > 0.0)
carbTimer.removeAutomationEventEatReminder()
automation.removeAutomationEventEatReminder()
if (sp.getBoolean(info.nightscout.core.ui.R.string.key_usebolusadvisor, false) && Profile.toMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0)
OKDialog.showYesNoCancel(ctx, rh.gs(info.nightscout.core.ui.R.string.bolus_advisor), rh.gs(info.nightscout.core.ui.R.string.bolus_advisor_message),
{ bolusAdvisorProcessing(ctx) },
@ -402,7 +400,7 @@ class BolusWizard @Inject constructor(
if (!result.success) {
uiInteraction.runAlarm(result.comment, rh.gs(info.nightscout.core.ui.R.string.treatmentdeliveryerror), info.nightscout.core.ui.R.raw.boluserror)
} else
carbTimer.scheduleAutomationEventEatReminder()
automation.scheduleAutomationEventEatReminder()
}
})
}
@ -494,7 +492,7 @@ class BolusWizard @Inject constructor(
bolusCalculatorResult?.let { persistenceLayer.insertOrUpdate(it) }
}
if (useAlarm && carbs > 0 && carbTime > 0) {
carbTimer.scheduleTimeToEatReminder(T.mins(carbTime.toLong()).secs().toInt())
automation.scheduleTimeToEatReminder(T.mins(carbTime.toLong()).secs().toInt())
}
}
})

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:tint="?attr/defaultTextColor"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/defaultTextColor"
android:pathData="M22,12l-4,-4v3H3v2h15v3z" />
</vector>

View file

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View file

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View file

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 7 KiB

After

Width:  |  Height:  |  Size: 7 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -165,6 +165,9 @@
<string name="isf_short">ISF</string>
<string name="canceling_tbr_failed">Canceling of temporary basal failed</string>
<string name="canceling_eb_failed">Canceling of extended bolus failed</string>
<string name="virtualpump_uploadstatus_title">Upload status to NS</string>
<string name="suspendloop_label">Disabled/Suspended loop</string>
<string name="iob_label">Insulin on Board (IOB)</string>
<!-- Protection-->
<string name="wrongpassword">Wrong password</string>

View file

@ -145,5 +145,8 @@
<string name="key_protection_timeout" translatable="false">protection_timeout</string>
<string name="key_objectiveuseloop" translatable="false">ObjectivesLoopUsed</string>
<string name="key_ObjectivesmanualEnacts" translatable="false">ObjectivesmanualEnacts</string>
<string name="key_objectiveuseactions" translatable="false">ObjectivesActionsUsed</string>
<string name="key_objectiveusescale" translatable="false">ObjectivesScaleUsed</string>
<string name="key_virtual_pump_upload_status" translatable="false">virtualpump_uploadstatus</string>
</resources>

View file

@ -11,24 +11,28 @@ files:
translation: /plugins/aps/src/main/res/values-%android_code%/strings.xml
- source: /plugins/main/src/main/res/values/strings.xml
translation: /plugins/main/src/main/res/values-%android_code%/strings.xml
- source: /plugins/main/src/main/res/values/exam.xml
translation: /plugins/main/src/main/res/values-%android_code%/%original_file_name%
- source: /plugins/main/src/main/res/values/objectives.xml
translation: /plugins/main/src/main/res/values-%android_code%/%original_file_name%
- source: /plugins/constraints/src/main/res/values/exam.xml
translation: /plugins/constraints/src/main/res/values-%android_code%/%original_file_name%
- source: /plugins/constraints/src/main/res/values/objectives.xml
translation: /plugins/constraints/src/main/res/values-%android_code%/%original_file_name%
- source: /plugins/automation/src/main/res/values/strings.xml
translation: /plugins/automation/src/main/res/values-%android_code%/strings.xml
- source: /plugins/openhumans/src/main/res/values/strings.xml
translation: /plugins/openhumans/src/main/res/values-%android_code%/strings.xml
- source: /plugins/sensitivity/src/main/res/values/strings.xml
translation: /plugins/sensitivity/src/main/res/values-%android_code%/strings.xml
- source: /plugins/source/src/main/res/values/strings.xml
translation: /plugins/source/src/main/res/values-%android_code%/strings.xml
- source: /plugins/insulin/src/main/res/values/strings.xml
translation: /plugins/insulin/src/main/res/values-%android_code%/strings.xml
- source: /plugins/configuration/src/main/res/values/strings.xml
translation: /plugins/configuration/src/main/res/values-%android_code%/strings.xml
- source: /plugins/sync/src/main/res/values/strings.xml
translation: /plugins/sync/src/main/res/values-%android_code%/strings.xml
translate_attributes: 0
content_segmentation: 0
- source: /plugins/support/src/main/res/values/strings.xml
translation: /plugins/support/src/main/res/values-%android_code%/strings.xml
- source: /plugins/constraints/src/main/res/values/strings.xml
translation: /plugins/constraints/src/main/res/values-%android_code%/strings.xml
- source: /core/graph/src/main/res/values/strings.xml
translation: /core/graph/src/main/res/values-%android_code%/strings.xml
- source: /core/interfaces/src/main/res/values/strings.xml
@ -69,6 +73,8 @@ files:
translation: /pump/omnipod-eros/src/main/res/values-%android_code%/strings.xml
- source: /pump/rileylink/src/main/res/values/strings.xml
translation: /pump/rileylink/src/main/res/values-%android_code%/strings.xml
- source: /pump/virtual/src/main/res/values/strings.xml
translation: /pump/virtual/src/main/res/values-%android_code%/strings.xml
- source: /insight/src/main/res/values/strings.xml
translation: /insight/src/main/res/values-%android_code%/strings.xml
- source: /insight/src/main/res/values/alert_codes.xml

View file

@ -19,14 +19,12 @@ dependencies {
implementation project(':app-wear-shared:shared')
implementation project(':database:entities')
implementation project(':database:impl')
implementation project(':plugins:automation')
implementation project(':core:main')
implementation project(':core:graph')
implementation project(':core:graphview')
implementation project(':core:interfaces')
implementation project(':core:ui')
implementation project(':core:utils')
implementation project(':ui')
// Protection
api 'androidx.biometric:biometric:1.1.0'

View file

@ -1,55 +0,0 @@
package info.nightscout.implementation
import dagger.android.HasAndroidInjector
import info.nightscout.automation.AutomationEventObject
import info.nightscout.automation.AutomationPlugin
import info.nightscout.automation.actions.ActionAlarm
import info.nightscout.automation.elements.Comparator
import info.nightscout.automation.elements.InputDelta
import info.nightscout.automation.triggers.TriggerBg
import info.nightscout.automation.triggers.TriggerConnector
import info.nightscout.automation.triggers.TriggerDelta
import info.nightscout.interfaces.BolusTimer
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.shared.interfaces.ResourceHelper
import java.text.DecimalFormat
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class BolusTimerImpl @Inject constructor(
private val injector: HasAndroidInjector,
private val rh: ResourceHelper,
private val automationPlugin: AutomationPlugin,
) : BolusTimer {
override fun scheduleAutomationEventBolusReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_reminder)
readOnly = true
systemAction = true
autoRemove = true
trigger = TriggerConnector(injector, TriggerConnector.Type.AND).apply {
// Bg above 70 mgdl and delta positive mgdl
list.add(TriggerBg(injector, 70.0, GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_GREATER))
list.add(
TriggerDelta(
injector, InputDelta(rh, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare
.IS_GREATER
)
)
}
actions.add(ActionAlarm(injector, rh.gs(R.string.time_to_bolus)))
}
automationPlugin.addIfNotExists(event)
}
override fun removeAutomationEventBolusReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_reminder)
}
automationPlugin.removeIfExists(event)
}
}

View file

@ -1,102 +0,0 @@
package info.nightscout.implementation
import dagger.android.HasAndroidInjector
import info.nightscout.automation.AutomationEventObject
import info.nightscout.automation.AutomationPlugin
import info.nightscout.automation.actions.ActionAlarm
import info.nightscout.automation.elements.Comparator
import info.nightscout.automation.elements.InputDelta
import info.nightscout.automation.triggers.TriggerBg
import info.nightscout.automation.triggers.TriggerConnector
import info.nightscout.automation.triggers.TriggerDelta
import info.nightscout.interfaces.CarbTimer
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.utils.TimerUtil
import info.nightscout.shared.interfaces.ResourceHelper
import java.text.DecimalFormat
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class CarbTimerImpl @Inject constructor(
private val injector: HasAndroidInjector,
private val rh: ResourceHelper,
private val automationPlugin: AutomationPlugin,
private val timerUtil: TimerUtil
) : CarbTimer {
/**
* Generate reminder via [info.nightscout.androidaps.utils.TimerUtil]
*
* @param seconds seconds to the future
*/
override fun scheduleTimeToEatReminder(seconds: Int) =
timerUtil.scheduleReminder(seconds, rh.gs(R.string.time_to_eat))
/**
* Create new Automation event to alarm when is time to eat
*/
override fun scheduleAutomationEventEatReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_advisor)
readOnly = true
systemAction = true
autoRemove = true
trigger = TriggerConnector(injector, TriggerConnector.Type.OR).apply {
// Bg under 180 mgdl and dropping by 15 mgdl
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 180.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(rh, -15.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(
TriggerDelta(
injector,
InputDelta(rh, -8.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE),
GlucoseUnit.MGDL,
Comparator.Compare.IS_EQUAL_OR_LESSER
)
)
})
// Bg under 160 mgdl and dropping by 9 mgdl
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 160.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(rh, -9.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(
TriggerDelta(
injector,
InputDelta(rh, -5.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE),
GlucoseUnit.MGDL,
Comparator.Compare.IS_EQUAL_OR_LESSER
)
)
})
// Bg under 145 mgdl and dropping
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 145.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(rh, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(
TriggerDelta(
injector,
InputDelta(rh, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE),
GlucoseUnit.MGDL,
Comparator.Compare.IS_EQUAL_OR_LESSER
)
)
})
}
actions.add(ActionAlarm(injector, rh.gs(R.string.time_to_eat)))
}
automationPlugin.addIfNotExists(event)
}
/**
* Remove Automation event
*/
override fun removeAutomationEventEatReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_advisor)
}
automationPlugin.removeIfExists(event)
}
}

View file

@ -13,6 +13,7 @@ import info.nightscout.database.entities.TemporaryBasal
import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.database.entities.TherapyEvent
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventEffectiveProfileSwitchChanged
import info.nightscout.rx.events.EventExtendedBolusChange
@ -27,24 +28,24 @@ import info.nightscout.rx.events.EventTherapyEventChange
import info.nightscout.rx.events.EventTreatmentChange
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.ui.widget.Widget
import io.reactivex.rxjava3.disposables.Disposable
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class CompatDBHelper @Inject constructor(
val aapsLogger: AAPSLogger,
val repository: AppRepository,
val rxBus: RxBus,
val context: Context
private val aapsLogger: AAPSLogger,
private val repository: AppRepository,
private val rxBus: RxBus,
private val context: Context,
private val uiInteraction: UiInteraction
) {
fun dbChangeDisposable(): Disposable = repository
.changeObservable()
.doOnSubscribe {
rxBus.send(EventNewBG(null))
Widget.updateWidget(context)
uiInteraction.updateWidget(context)
}
.subscribe {
/**
@ -57,7 +58,7 @@ class CompatDBHelper @Inject constructor(
it.filterIsInstance<GlucoseValue>().maxByOrNull { gv -> gv.timestamp }?.let { gv ->
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg $gv")
rxBus.send(EventNewBG(gv.timestamp))
Widget.updateWidget(context)
uiInteraction.updateWidget(context)
newestGlucoseValue = gv
}
it.filterIsInstance<GlucoseValue>().minOfOrNull { gv -> gv.timestamp }?.let { timestamp ->

View file

@ -6,6 +6,7 @@ import info.nightscout.database.ValueWrapper
import info.nightscout.database.entities.Bolus
import info.nightscout.database.entities.BolusCalculatorResult
import info.nightscout.database.entities.Carbs
import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.database.entities.UserEntry
import info.nightscout.database.impl.AppRepository
@ -68,4 +69,5 @@ class PersistenceLayerImpl @Inject constructor(
override fun getTemporaryTargetActiveAt(timestamp: Long): Single<ValueWrapper<TemporaryTarget>> = repository.getTemporaryTargetActiveAt(timestamp)
override fun getUserEntryFilteredDataFromTime(timestamp: Long): Single<List<UserEntry>> = repository.getUserEntryFilteredDataFromTime(timestamp)
override fun getEffectiveProfileSwitchActiveAt(timestamp: Long): Single<ValueWrapper<EffectiveProfileSwitch>> = repository.getEffectiveProfileSwitchActiveAt(timestamp)
}

View file

@ -4,8 +4,6 @@ import dagger.Binds
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.core.graph.OverviewData
import info.nightscout.implementation.BolusTimerImpl
import info.nightscout.implementation.CarbTimerImpl
import info.nightscout.implementation.DefaultValueHelperImpl
import info.nightscout.implementation.HardLimitsImpl
import info.nightscout.implementation.LocalAlertUtilsImpl
@ -14,14 +12,12 @@ import info.nightscout.implementation.TrendCalculatorImpl
import info.nightscout.implementation.UserEntryLoggerImpl
import info.nightscout.implementation.XDripBroadcastImpl
import info.nightscout.implementation.androidNotification.NotificationHolderImpl
import info.nightscout.implementation.constraints.ConstraintsImpl
import info.nightscout.implementation.db.PersistenceLayerImpl
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.implementation.logging.LoggerUtilsImpl
import info.nightscout.implementation.overview.OverviewDataImpl
import info.nightscout.implementation.plugin.PluginStore
import info.nightscout.implementation.profile.ProfileFunctionImpl
import info.nightscout.implementation.profile.ProfileInstantiatorImpl
import info.nightscout.implementation.profile.ProfileStoreObject
import info.nightscout.implementation.profiling.ProfilerImpl
import info.nightscout.implementation.protection.PasswordCheckImpl
@ -41,13 +37,10 @@ import info.nightscout.implementation.stats.TddCalculatorImpl
import info.nightscout.implementation.stats.TirCalculatorImpl
import info.nightscout.implementation.storage.FileStorage
import info.nightscout.implementation.userEntry.UserEntryPresentationHelperImpl
import info.nightscout.interfaces.BolusTimer
import info.nightscout.interfaces.CarbTimer
import info.nightscout.interfaces.LocalAlertUtils
import info.nightscout.interfaces.NotificationHolder
import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.XDripBroadcast
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.db.PersistenceLayer
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.logging.LoggerUtils
@ -55,7 +48,6 @@ import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileInstantiator
import info.nightscout.interfaces.profiling.Profiler
import info.nightscout.interfaces.protection.PasswordCheck
import info.nightscout.interfaces.protection.ProtectionCheck
@ -106,7 +98,6 @@ abstract class ImplementationModule {
@Binds fun bindWarnColors(warnColorsImpl: WarnColorsImpl): WarnColors
@Binds fun bindHardLimits(hardLimitsImpl: HardLimitsImpl): HardLimits
@Binds fun bindResourceHelper(resourceHelperImpl: ResourceHelperImpl): ResourceHelper
@Binds fun bindProfileStoreInstantiator(profileStoreInstantiatorImpl: ProfileInstantiatorImpl): ProfileInstantiator
@Binds fun bindBlePreCheck(blePreCheckImpl: BlePreCheckImpl): BlePreCheck
@Binds fun bindTrendCalculatorInterface(trendCalculator: TrendCalculatorImpl): TrendCalculator
@ -115,13 +106,10 @@ abstract class ImplementationModule {
@Binds fun bindDexcomTirCalculatorInterface(dexcomTirCalculator: DexcomTirCalculatorImpl): DexcomTirCalculator
@Binds fun bindPumpSyncInterface(pumpSyncImplementation: PumpSyncImplementation): PumpSync
@Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast
@Binds fun bindCarbTimerInterface(carbTimer: CarbTimerImpl): CarbTimer
@Binds fun bindBolusTimerInterface(bolusTimer: BolusTimerImpl): BolusTimer
@Binds fun bindLocalAlertUtilsInterface(localAlertUtils: LocalAlertUtilsImpl): LocalAlertUtils
@Binds fun bindIconsProviderInterface(iconsProvider: IconsProviderImplementation): IconsProvider
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder
@Binds fun bindCommandQueue(commandQueue: CommandQueueImplementation): CommandQueue
@Binds fun bindsConstraints(constraintsImpl: ConstraintsImpl): Constraints
@Binds fun bindsProfileFunction(profileFunctionImpl: ProfileFunctionImpl): ProfileFunction
@Binds fun bindsStorage(fileStorage: FileStorage): Storage
@Binds fun bindsReceiverStatusStore(receiverStatusStoreImpl: ReceiverStatusStoreImpl): ReceiverStatusStore

View file

@ -1,17 +0,0 @@
package info.nightscout.implementation.profile
import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.profile.ProfileInstantiator
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.shared.utils.DateUtil
import org.json.JSONObject
import javax.inject.Inject
class ProfileInstantiatorImpl @Inject constructor(
private val injector: HasAndroidInjector,
private val dateUtil: DateUtil
): ProfileInstantiator {
override fun storeInstance(jsonObject: JSONObject): ProfileStore =
ProfileStoreObject(injector, jsonObject, dateUtil)
}

View file

@ -11,9 +11,9 @@ class IconsProviderImplementation @Inject constructor(private val config: Config
override fun getIcon(): Int =
when {
config.NSCLIENT -> info.nightscout.ui.R.mipmap.ic_yellowowl
config.PUMPCONTROL -> info.nightscout.ui.R.mipmap.ic_pumpcontrol
else -> info.nightscout.ui.R.mipmap.ic_launcher
config.NSCLIENT -> info.nightscout.core.ui.R.mipmap.ic_yellowowl
config.PUMPCONTROL -> info.nightscout.core.ui.R.mipmap.ic_pumpcontrol
else -> info.nightscout.core.ui.R.mipmap.ic_launcher
}
override fun getNotificationIcon(): Int =

View file

@ -81,7 +81,7 @@ class UserEntryPresentationHelperImpl @Inject constructor(
Sources.Maintenance -> info.nightscout.core.ui.R.drawable.ic_maintenance
Sources.NSClient -> info.nightscout.core.ui.R.drawable.ic_nightscout_syncs
Sources.NSProfile -> R.drawable.ic_nightscout_profile
Sources.Objectives -> R.drawable.ic_graduation
Sources.Objectives -> info.nightscout.core.ui.R.drawable.ic_graduation
Sources.Pump -> info.nightscout.core.ui.R.drawable.ic_generic_icon
Sources.Dana -> info.nightscout.core.ui.R.drawable.ic_danars_128
Sources.DanaR -> info.nightscout.core.ui.R.drawable.ic_danars_128

View file

@ -5,8 +5,6 @@
<string name="bg_label">BG</string>
<string name="time_to_eat">Time to eat</string>
<string name="time_to_bolus">Time to bolus!\nRun Bolus wizard and do calculation again.</string>
<string name="executing_right_now">Command is executed right now</string>
<string name="basal_value_below_minimum">Basal value below minimum. Profile not set!</string>
<string name="permission">Permission</string>

View file

@ -85,7 +85,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
}
val injector = HasAndroidInjector {
private val injector = HasAndroidInjector {
AndroidInjector {
if (it is Command) {
it.aapsLogger = aapsLogger

View file

@ -1,9 +1,10 @@
package info.nightscout.core.aps
package info.nightscout.plugins.aps
import android.text.Spanned
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.convertedToAbsolute
import info.nightscout.core.extensions.convertedToPercent
import info.nightscout.core.ui.R
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.constraints.Constraint
@ -14,7 +15,7 @@ import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.pump.defs.PumpDescription
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper.fromHtml
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
@ -41,7 +42,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var dateUtil: DateUtil
var date: Long = 0
override var date: Long = 0
override var reason: String = ""
override var rate = 0.0
override var percent = 0
@ -116,11 +117,11 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
// reason
ret += "<b>" + rh.gs(info.nightscout.core.ui.R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;")
return fromHtml(ret)
return HtmlHelper.fromHtml(ret)
}
return if (isCarbsRequired) {
fromHtml(carbsRequiredText)
} else fromHtml(rh.gs(info.nightscout.core.ui.R.string.nochangerequested))
HtmlHelper.fromHtml(carbsRequiredText)
} else HtmlHelper.fromHtml(rh.gs(R.string.nochangerequested))
}
override fun newAndClone(injector: HasAndroidInjector): APSResult {

View file

@ -3,8 +3,10 @@ package info.nightscout.plugins.aps.di
import dagger.Binds
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.autotune.Autotune
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.plugins.aps.OpenAPSFragment
import info.nightscout.plugins.aps.loop.LoopPlugin
import info.nightscout.plugins.general.autotune.AutotunePlugin
@ -22,6 +24,7 @@ import info.nightscout.plugins.general.autotune.AutotunePlugin
abstract class ApsModule {
@ContributesAndroidInjector abstract fun contributesOpenAPSFragment(): OpenAPSFragment
@ContributesAndroidInjector abstract fun apsResultInjector(): APSResultObject
@Module
interface Bindings {

View file

@ -2,10 +2,12 @@ package info.nightscout.plugins.aps.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.plugins.aps.loop.CarbSuggestionReceiver
import info.nightscout.plugins.aps.loop.LoopFragment
@Module
@Suppress("unused")
abstract class LoopModule {
@ContributesAndroidInjector abstract fun contributesLoopFragment(): info.nightscout.plugins.aps.loop.LoopFragment
@ContributesAndroidInjector abstract fun contributesCarbSuggestionReceiver(): info.nightscout.plugins.aps.loop.CarbSuggestionReceiver
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
@ContributesAndroidInjector abstract fun contributesCarbSuggestionReceiver(): CarbSuggestionReceiver
}

View file

@ -782,6 +782,7 @@ class LoopPlugin @Inject constructor(
configuration = runningConfiguration.configuration().toString()
)
}
companion object {
private const val CHANNEL_ID = "AAPS-OpenLoop"

View file

@ -1,7 +1,7 @@
package info.nightscout.plugins.aps.openAPSAMA
import dagger.android.HasAndroidInjector
import info.nightscout.core.aps.APSResultObject
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.core.extensions.convertedToAbsolute
import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.core.extensions.plannedRemainingMinutes

View file

@ -1,7 +1,7 @@
package info.nightscout.plugins.aps.openAPSAMA
import dagger.android.HasAndroidInjector
import info.nightscout.core.aps.APSResultObject
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.rx.logging.LTag
import org.json.JSONException
import org.json.JSONObject

View file

@ -1,7 +1,7 @@
package info.nightscout.plugins.aps.openAPSSMB
import dagger.android.HasAndroidInjector
import info.nightscout.core.aps.APSResultObject
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.core.extensions.convertedToAbsolute
import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.core.extensions.plannedRemainingMinutes

View file

@ -1,7 +1,7 @@
package info.nightscout.plugins.aps.openAPSSMB
import dagger.android.HasAndroidInjector
import info.nightscout.core.aps.APSResultObject
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.interfaces.aps.VariableSensitivityResult
import info.nightscout.rx.logging.LTag
import org.json.JSONException

View file

@ -30,7 +30,7 @@ import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileInstantiator
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.MidnightTime
@ -70,7 +70,7 @@ class AutotuneFragment : DaggerFragment() {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var profileInstantiator: ProfileInstantiator
@Inject lateinit var instantiator: Instantiator
private var disposable: CompositeDisposable = CompositeDisposable()
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
@ -97,7 +97,7 @@ class AutotuneFragment : DaggerFragment() {
if (autotunePlugin.lastNbDays.isEmpty())
autotunePlugin.lastNbDays = sp.getInt(info.nightscout.core.utils.R.string.key_autotune_default_tune_days, 5).toString()
val defaultValue = sp.getInt(info.nightscout.core.utils.R.string.key_autotune_default_tune_days, 5).toDouble()
profileStore = activePlugin.activeProfileSource.profile ?: profileInstantiator.storeInstance(JSONObject())
profileStore = activePlugin.activeProfileSource.profile ?: instantiator.provideProfileStore(JSONObject())
profileName = if (binding.profileList.text.toString() == rh.gs(info.nightscout.core.ui.R.string.active)) "" else binding.profileList.text.toString()
profileFunction.getProfile()?.let { currentProfile ->
profile = ATProfile(profileStore.getSpecificProfile(profileName)?.let { ProfileSealed.Pure(it) } ?: currentProfile, LocalInsulin(""), injector)
@ -295,7 +295,7 @@ class AutotuneFragment : DaggerFragment() {
@Synchronized
private fun updateGui() {
_binding ?: return
profileStore = activePlugin.activeProfileSource.profile ?: profileInstantiator.storeInstance(JSONObject())
profileStore = activePlugin.activeProfileSource.profile ?: instantiator.provideProfileStore(JSONObject())
profileName = if (binding.profileList.text.toString() == rh.gs(info.nightscout.core.ui.R.string.active)) "" else binding.profileList.text.toString()
profileFunction.getProfile()?.let { currentProfile ->
profile = ATProfile(profileStore.getSpecificProfile(profileName)?.let { ProfileSealed.Pure(it) } ?: currentProfile, LocalInsulin(""), injector)

View file

@ -16,7 +16,7 @@ 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.profile.ProfileInstantiator
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.plugins.aps.R
@ -61,7 +61,7 @@ class AutotunePlugin @Inject constructor(
private val config: Config,
private val uel: UserEntryLogger,
aapsLogger: AAPSLogger,
private val profileInstantiator: ProfileInstantiator
private val instantiator: Instantiator
) : PluginBase(
PluginDescription()
.mainType(PluginType.GENERAL)
@ -325,7 +325,7 @@ class AutotunePlugin @Inject constructor(
if (newProfile == null) return
val profilePlugin = activePlugin.activeProfileSource
val circadian = sp.getBoolean(info.nightscout.core.utils.R.string.key_autotune_circadian_ic_isf, false)
val profileStore = activePlugin.activeProfileSource.profile ?: profileInstantiator.storeInstance(JSONObject())
val profileStore = activePlugin.activeProfileSource.profile ?: instantiator.provideProfileStore(JSONObject())
val profileList: ArrayList<CharSequence> = profileStore.getProfileList()
var indexLocalProfile = -1
for (p in profileList.indices)

View file

@ -12,7 +12,7 @@ import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileInstantiator
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.profile.PureProfile
import info.nightscout.interfaces.utils.Round
@ -38,7 +38,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
@Inject lateinit var config: Config
@Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var profileInstantiator: ProfileInstantiator
@Inject lateinit var instantiator: Instantiator
var profile: ProfileSealed
var circadianProfile: ProfileSealed
@ -179,7 +179,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
json.put("defaultProfile", profilename)
json.put("store", store)
json.put("startDate", dateUtil.toISOAsUTC(dateUtil.now()))
profileStore = profileInstantiator.storeInstance(json)
profileStore = instantiator.provideProfileStore(json)
} catch (e: JSONException) {
}
return profileStore

View file

@ -38,6 +38,7 @@ open class TestBaseWithProfile : TestBase() {
@Mock lateinit var context: Context
lateinit var dateUtil: DateUtil
lateinit var testPumpPlugin: TestPumpPlugin
val rxBus = RxBus(aapsSchedulers, aapsLogger)
val profileInjector = HasAndroidInjector { AndroidInjector { } }
@ -56,6 +57,8 @@ open class TestBaseWithProfile : TestBase() {
dateUtil = Mockito.spy(DateUtil(context))
`when`(dateUtil.now()).thenReturn(1656358822000)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
testPumpPlugin = TestPumpPlugin(profileInjector)
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
effectiveProfileSwitch = EffectiveProfileSwitch(
timestamp = dateUtil.now(),
basalBlocks = validProfile.basalBlocks,

View file

@ -1,17 +1,16 @@
package info.nightscout.androidaps.plugins.aps.loop
package info.nightscout.plugins.aps.loop
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.core.aps.APSResultObject
import info.nightscout.database.entities.TemporaryBasal
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.pump.defs.PumpType
import info.nightscout.interfaces.utils.JsonHelper.safeGetDouble
import org.junit.Assert
import info.nightscout.shared.sharedPreferences.SP
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers
@ -21,7 +20,7 @@ import org.mockito.Mockito.`when`
class APSResultTest : TestBaseWithProfile() {
@Mock lateinit var constraints: Constraints
@Mock lateinit var iobCobCalculator: IobCobCalculator
@Mock lateinit var sp: SP
private val injector = HasAndroidInjector { AndroidInjector { } }
@ -55,7 +54,7 @@ class APSResultTest : TestBaseWithProfile() {
@Test
fun changeRequestedTest() {
val apsResult = APSResultObject { AndroidInjector { } }
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
.also {
it.aapsLogger = aapsLogger
it.constraintChecker = constraints
@ -76,21 +75,21 @@ class APSResultTest : TestBaseWithProfile() {
closedLoopEnabled.set(aapsLogger, true)
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
apsResult.tempBasalRequested(false)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
apsResult.tempBasalRequested(true).percent(200).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// open loop
closedLoopEnabled.set(aapsLogger, false)
// no change requested
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
apsResult.tempBasalRequested(false)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
// request 100% when no temp is running
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
apsResult.tempBasalRequested(true).percent(100).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
// request equal temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -103,7 +102,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).percent(70).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
// request zero temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -116,7 +115,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).percent(0).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// request high temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -129,7 +128,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).percent(200).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// request slightly different temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -142,7 +141,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).percent(80).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
// request different temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -155,7 +154,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).percent(120).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// it should work with absolute temps too
// request different temp
@ -169,7 +168,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).percent(100).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
TemporaryBasal(
timestamp = 0,
@ -180,7 +179,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).percent(50).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// **** ABSOLUTE pump ****
testPumpPlugin.pumpDescription.fillFor(PumpType.MEDTRONIC_515_715) // U/h based
@ -191,7 +190,7 @@ class APSResultTest : TestBaseWithProfile() {
// request 100% when no temp is running
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
apsResult.tempBasalRequested(true).rate(1.0).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
// request equal temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -204,7 +203,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(2.0).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
TemporaryBasal(
timestamp = 0,
@ -215,7 +214,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(2.0).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
// request zero temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -228,7 +227,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(0.0).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// request high temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -241,7 +240,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(35.0).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// request slightly different temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -254,7 +253,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(1.2).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
// request different temp
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
@ -267,7 +266,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(1.5).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
// it should work with percent temps too
// request different temp
@ -281,7 +280,7 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(1.1).duration(30)
Assert.assertEquals(false, apsResult.isChangeRequested)
Assertions.assertEquals(false, apsResult.isChangeRequested)
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(
TemporaryBasal(
timestamp = 0,
@ -292,11 +291,11 @@ class APSResultTest : TestBaseWithProfile() {
)
)
apsResult.tempBasalRequested(true).rate(0.5).duration(30)
Assert.assertEquals(true, apsResult.isChangeRequested)
Assertions.assertEquals(true, apsResult.isChangeRequested)
}
@Test fun cloneTest() {
val apsResult = APSResultObject { AndroidInjector { } }
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
.also {
it.aapsLogger = aapsLogger
it.constraintChecker = constraints
@ -308,12 +307,12 @@ class APSResultTest : TestBaseWithProfile() {
}
apsResult.rate(10.0)
val apsResult2 = apsResult.newAndClone(injector)
Assert.assertEquals(apsResult.rate, apsResult2.rate, 0.0)
Assertions.assertEquals(apsResult.rate, apsResult2.rate, 0.0)
}
@Test fun jsonTest() {
closedLoopEnabled.set(aapsLogger, true)
val apsResult = APSResultObject { AndroidInjector { } }
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
.also {
it.aapsLogger = aapsLogger
it.constraintChecker = constraints
@ -324,9 +323,9 @@ class APSResultTest : TestBaseWithProfile() {
it.rh = rh
}
apsResult.rate(20.0).tempBasalRequested(true)
Assert.assertEquals(20.0, safeGetDouble(apsResult.json(), "rate"), 0.0)
Assertions.assertEquals(20.0, safeGetDouble(apsResult.json(), "rate"), 0.0)
apsResult.rate(20.0).tempBasalRequested(false)
Assert.assertEquals(false, apsResult.json()?.has("rate"))
Assertions.assertEquals(false, apsResult.json()?.has("rate"))
}
@BeforeEach

View file

@ -28,6 +28,7 @@ dependencies {
implementation project(':core:interfaces')
testImplementation project(':implementation')
testImplementation project(':plugins:main')
api "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
api "com.google.android.gms:play-services-location:$play_services_location_version"

View file

@ -17,6 +17,8 @@ import info.nightscout.automation.actions.ActionSendSMS
import info.nightscout.automation.actions.ActionStartTempTarget
import info.nightscout.automation.actions.ActionStopProcessing
import info.nightscout.automation.actions.ActionStopTempTarget
import info.nightscout.automation.elements.Comparator
import info.nightscout.automation.elements.InputDelta
import info.nightscout.automation.events.EventAutomationDataChanged
import info.nightscout.automation.events.EventAutomationUpdateGui
import info.nightscout.automation.events.EventLocationChange
@ -41,6 +43,7 @@ import info.nightscout.automation.triggers.TriggerTimeRange
import info.nightscout.automation.triggers.TriggerWifiSsid
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.automation.Automation
import info.nightscout.interfaces.automation.AutomationEvent
@ -50,6 +53,7 @@ import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.utils.TimerUtil
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventBTChange
@ -67,6 +71,7 @@ import io.reactivex.rxjava3.kotlin.plusAssign
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.text.DecimalFormat
import java.util.Collections
import javax.inject.Inject
import javax.inject.Singleton
@ -87,7 +92,8 @@ class AutomationPlugin @Inject constructor(
private val config: Config,
private val locationServiceHelper: LocationServiceHelper,
private val dateUtil: DateUtil,
private val activePlugin: ActivePlugin
private val activePlugin: ActivePlugin,
private val timerUtil: TimerUtil
) : PluginBase(
PluginDescription()
.mainType(PluginType.GENERAL)
@ -402,4 +408,109 @@ class AutomationPlugin @Inject constructor(
TriggerBTDevice(injector),
)
}
/**
* Generate reminder via [info.nightscout.interfaces.utils.TimerUtil]
*
* @param seconds seconds to the future
*/
override fun scheduleTimeToEatReminder(seconds: Int) =
timerUtil.scheduleReminder(seconds, rh.gs(R.string.time_to_eat))
/**
* Create new Automation event to alarm when is time to eat
*/
override fun scheduleAutomationEventEatReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_advisor)
readOnly = true
systemAction = true
autoRemove = true
trigger = TriggerConnector(injector, TriggerConnector.Type.OR).apply {
// Bg under 180 mgdl and dropping by 15 mgdl
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 180.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(rh, -15.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(
TriggerDelta(
injector,
InputDelta(rh, -8.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE),
GlucoseUnit.MGDL,
Comparator.Compare.IS_EQUAL_OR_LESSER
)
)
})
// Bg under 160 mgdl and dropping by 9 mgdl
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 160.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(rh, -9.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(
TriggerDelta(
injector,
InputDelta(rh, -5.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE),
GlucoseUnit.MGDL,
Comparator.Compare.IS_EQUAL_OR_LESSER
)
)
})
// Bg under 145 mgdl and dropping
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
list.add(TriggerBg(injector, 145.0, GlucoseUnit.MGDL, Comparator.Compare.IS_LESSER))
list.add(TriggerDelta(injector, InputDelta(rh, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
list.add(
TriggerDelta(
injector,
InputDelta(rh, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE),
GlucoseUnit.MGDL,
Comparator.Compare.IS_EQUAL_OR_LESSER
)
)
})
}
actions.add(ActionAlarm(injector, rh.gs(R.string.time_to_eat)))
}
addIfNotExists(event)
}
/**
* Remove Automation event
*/
override fun removeAutomationEventEatReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_advisor)
}
removeIfExists(event)
}
override fun scheduleAutomationEventBolusReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_reminder)
readOnly = true
systemAction = true
autoRemove = true
trigger = TriggerConnector(injector, TriggerConnector.Type.AND).apply {
// Bg above 70 mgdl and delta positive mgdl
list.add(TriggerBg(injector, 70.0, GlucoseUnit.MGDL, Comparator.Compare.IS_EQUAL_OR_GREATER))
list.add(
TriggerDelta(
injector, InputDelta(rh, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), GlucoseUnit.MGDL, Comparator.Compare
.IS_GREATER
)
)
}
actions.add(ActionAlarm(injector, rh.gs(R.string.time_to_bolus)))
}
addIfNotExists(event)
}
override fun removeAutomationEventBolusReminder() {
val event = AutomationEventObject(injector).apply {
title = rh.gs(info.nightscout.core.ui.R.string.bolus_reminder)
}
removeIfExists(event)
}
}

View file

@ -131,4 +131,8 @@
<string name="saturday_short">S</string>
<string name="sunday_short">S</string>
<!-- Reminders-->
<string name="time_to_eat">Time to eat!\nRun Bolus wizard and do calculation again.</string>
<string name="time_to_bolus">Time to bolus!\nRun Bolus wizard and do calculation again.</string>
</resources>

View file

@ -1,10 +1,9 @@
package info.nightscout.implementation
package info.nightscout.automation
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.automation.AutomationPlugin
import info.nightscout.automation.services.LocationServiceHelper
import info.nightscout.automation.triggers.Trigger
import info.nightscout.core.utils.fabric.FabricPrivacy
@ -14,16 +13,17 @@ import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.TimerUtil
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.`when`
import org.mockito.Mockito
class BolusTimerImplTest : TestBase() {
@ -38,6 +38,7 @@ class BolusTimerImplTest : TestBase() {
@Mock lateinit var locationServiceHelper: LocationServiceHelper
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var timerUtil: TimerUtil
private val injector = HasAndroidInjector {
AndroidInjector {
@ -50,23 +51,22 @@ class BolusTimerImplTest : TestBase() {
private lateinit var dateUtil: DateUtil
private lateinit var automationPlugin: AutomationPlugin
private lateinit var sut: BolusTimerImpl
@BeforeEach
fun init() {
`when`(rh.gs(anyInt())).thenReturn("")
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
Mockito.`when`(rh.gs(anyInt())).thenReturn("")
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
dateUtil = DateUtil(context)
automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil, activePlugin)
sut = BolusTimerImpl(injector, rh, automationPlugin)
automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil,
activePlugin, timerUtil)
}
@Test
fun doTest() {
Assert.assertEquals(0, automationPlugin.size())
sut.scheduleAutomationEventBolusReminder()
Assert.assertEquals(1, automationPlugin.size())
sut.removeAutomationEventBolusReminder()
Assert.assertEquals(0, automationPlugin.size())
Assertions.assertEquals(0, automationPlugin.size())
automationPlugin.scheduleAutomationEventBolusReminder()
Assertions.assertEquals(1, automationPlugin.size())
automationPlugin.removeAutomationEventBolusReminder()
Assertions.assertEquals(0, automationPlugin.size())
}
}

View file

@ -1,10 +1,9 @@
package info.nightscout.implementation
package info.nightscout.automation
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.automation.AutomationPlugin
import info.nightscout.automation.services.LocationServiceHelper
import info.nightscout.automation.triggers.Trigger
import info.nightscout.core.utils.fabric.FabricPrivacy
@ -19,14 +18,13 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.`when`
class CarbTimerImplTest : TestBase() {
@ -54,27 +52,26 @@ class CarbTimerImplTest : TestBase() {
private lateinit var timerUtil: TimerUtil
private lateinit var automationPlugin: AutomationPlugin
private lateinit var sut: CarbTimerImpl
@BeforeEach
fun init() {
`when`(rh.gs(anyInt())).thenReturn("")
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
Mockito.`when`(rh.gs(anyInt())).thenReturn("")
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
dateUtil = DateUtil(context)
timerUtil = TimerUtil(context)
automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil, activePlugin)
sut = CarbTimerImpl(injector, rh, automationPlugin, timerUtil)
automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil,
activePlugin, timerUtil)
}
@Test
fun doTest() {
Assert.assertEquals(0, automationPlugin.size())
sut.scheduleAutomationEventEatReminder()
Assert.assertEquals(1, automationPlugin.size())
sut.removeAutomationEventEatReminder()
Assert.assertEquals(0, automationPlugin.size())
Assertions.assertEquals(0, automationPlugin.size())
automationPlugin.scheduleAutomationEventEatReminder()
Assertions.assertEquals(1, automationPlugin.size())
automationPlugin.removeAutomationEventEatReminder()
Assertions.assertEquals(0, automationPlugin.size())
sut.scheduleTimeToEatReminder(1)
automationPlugin.scheduleTimeToEatReminder(1)
Mockito.verify(context, Mockito.times(1)).startActivity(any())
}
}

View file

@ -75,6 +75,7 @@ ActionsTestBase : TestBaseWithProfile() {
runningConfiguration: RunningConfiguration,
version: String
): DeviceStatus? = null
override fun setPluginEnabled(type: PluginType, newState: Boolean) {}
}

View file

@ -3,9 +3,9 @@ package info.nightscout.automation.triggers
import com.google.common.base.Optional
import info.nightscout.automation.R
import info.nightscout.automation.elements.Comparator
import info.nightscout.core.iob.iobCobCalculator.data.AutosensDataObject
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
import org.json.JSONObject
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers
@ -22,53 +22,53 @@ class TriggerAutosensValueTest : TriggerTestBase() {
var t = TriggerAutosensValue(injector)
t.autosens.value = 110.0
t.comparator.value = Comparator.Compare.IS_EQUAL
Assert.assertEquals(110.0, t.autosens.value, 0.01)
Assert.assertEquals(Comparator.Compare.IS_EQUAL, t.comparator.value)
Assert.assertFalse(t.shouldRun())
Assertions.assertEquals(110.0, t.autosens.value, 0.01)
Assertions.assertEquals(Comparator.Compare.IS_EQUAL, t.comparator.value)
Assertions.assertFalse(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 100.0
t.comparator.value = Comparator.Compare.IS_EQUAL
Assert.assertEquals(100.0, t.autosens.value, 0.01)
Assert.assertTrue(t.shouldRun())
Assertions.assertEquals(100.0, t.autosens.value, 0.01)
Assertions.assertTrue(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 50.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_GREATER
Assert.assertTrue(t.shouldRun())
Assertions.assertTrue(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 310.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
Assert.assertTrue(t.shouldRun())
Assertions.assertTrue(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 420.0
t.comparator.value = Comparator.Compare.IS_EQUAL
Assert.assertFalse(t.shouldRun())
Assertions.assertFalse(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 390.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
Assert.assertTrue(t.shouldRun())
Assertions.assertTrue(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 390.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_GREATER
Assert.assertFalse(t.shouldRun())
Assertions.assertFalse(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 20.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_GREATER
Assert.assertTrue(t.shouldRun())
Assertions.assertTrue(t.shouldRun())
t = TriggerAutosensValue(injector)
t.autosens.value = 390.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
Assert.assertTrue(t.shouldRun())
Assertions.assertTrue(t.shouldRun())
`when`(autosensDataStore.getLastAutosensData(anyObject(), anyObject(), anyObject())).thenReturn(AutosensDataObject(injector))
t = TriggerAutosensValue(injector)
t.autosens.value = 80.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
Assert.assertFalse(t.shouldRun())
Assertions.assertFalse(t.shouldRun())
// Test autosensData == null and Comparator == IS_NOT_AVAILABLE
`when`(autosensDataStore.getLastAutosensData(anyObject(), anyObject(), anyObject())).thenReturn(null)
t = TriggerAutosensValue(injector)
t.comparator.value = Comparator.Compare.IS_NOT_AVAILABLE
Assert.assertTrue(t.shouldRun())
Assertions.assertTrue(t.shouldRun())
}
@Test
@ -77,8 +77,8 @@ class TriggerAutosensValueTest : TriggerTestBase() {
t.autosens.value = 213.0
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
val t1 = t.duplicate() as TriggerAutosensValue
Assert.assertEquals(213.0, t1.autosens.value, 0.01)
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
Assertions.assertEquals(213.0, t1.autosens.value, 0.01)
Assertions.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var asJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"value\":410},\"type\":\"TriggerAutosensValue\"}"
@ -88,7 +88,7 @@ class TriggerAutosensValueTest : TriggerTestBase() {
val t = TriggerAutosensValue(injector)
t.autosens.value = 410.0
t.comparator.value = Comparator.Compare.IS_EQUAL
Assert.assertEquals(asJson, t.toJSON())
Assertions.assertEquals(asJson, t.toJSON())
}
@Test
@ -97,12 +97,12 @@ class TriggerAutosensValueTest : TriggerTestBase() {
t.autosens.value = 410.0
t.comparator.value = Comparator.Compare.IS_EQUAL
val t2 = TriggerDummy(injector).instantiate(JSONObject(t.toJSON())) as TriggerAutosensValue
Assert.assertEquals(Comparator.Compare.IS_EQUAL, t2.comparator.value)
Assert.assertEquals(410.0, t2.autosens.value, 0.01)
Assertions.assertEquals(Comparator.Compare.IS_EQUAL, t2.comparator.value)
Assertions.assertEquals(410.0, t2.autosens.value, 0.01)
}
@Test fun iconTest() {
Assert.assertEquals(Optional.of(R.drawable.ic_as), TriggerAutosensValue(injector).icon())
Assertions.assertEquals(Optional.of(R.drawable.ic_as), TriggerAutosensValue(injector).icon())
}
@BeforeEach

View file

@ -59,7 +59,7 @@ class RunningConfigurationImpl @Inject constructor(
json.put("insulinConfiguration", insulinInterface.configuration())
json.put("sensitivity", sensitivityInterface.id.value)
json.put("sensitivityConfiguration", sensitivityInterface.configuration())
json.put("smoothing", smoothingInterface?.javaClass?.simpleName)
json.put("smoothing", smoothingInterface.javaClass.simpleName)
json.put("overviewConfiguration", overviewInterface.configuration())
json.put("safetyConfiguration", safetyInterface.configuration())
json.put("pump", pumpInterface.model().description)

View file

@ -12,7 +12,7 @@ apply from: "${project.rootDir}/core/main/test_dependencies.gradle"
apply from: "${project.rootDir}/core/main/allopen_dependencies.gradle"
apply from: "${project.rootDir}/core/main/jacoco_global.gradle"
android {
namespace 'info.nightscout.plugins.support'
namespace 'info.nightscout.plugins.constraints'
}
dependencies {
@ -20,6 +20,7 @@ dependencies {
implementation project(':core:interfaces')
implementation project(':core:ui')
implementation project(':core:utils')
implementation project(':core:validators')
implementation project(':database:entities')
// Phone checker

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>
</manifest>

View file

@ -1,4 +1,4 @@
package info.nightscout.implementation.constraints
package info.nightscout.plugins.constraints
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints

View file

@ -12,7 +12,7 @@ import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.source.DexcomBoyda
import info.nightscout.plugins.support.R
import info.nightscout.plugins.constraints.R
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventBucketedDataCreated

View file

@ -0,0 +1,25 @@
package info.nightscout.plugins.constraints.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
@Suppress("unused")
abstract class ObjectivesModule {
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): info.nightscout.plugins.constraints.objectives.ObjectivesFragment
@ContributesAndroidInjector abstract fun contributesObjectivesExamDialog(): info.nightscout.plugins.constraints.objectives.activities.ObjectivesExamDialog
@ContributesAndroidInjector abstract fun contributesNtpProgressDialog(): info.nightscout.plugins.constraints.objectives.dialogs.NtpProgressDialog
@ContributesAndroidInjector abstract fun objectiveInjector(): info.nightscout.plugins.constraints.objectives.objectives.Objective
@ContributesAndroidInjector abstract fun objective0Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective0
@ContributesAndroidInjector abstract fun objective1Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective1
@ContributesAndroidInjector abstract fun objective2Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective2
@ContributesAndroidInjector abstract fun objective3Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective3
@ContributesAndroidInjector abstract fun objective4Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective4
@ContributesAndroidInjector abstract fun objective5Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective5
@ContributesAndroidInjector abstract fun objective6Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective6
@ContributesAndroidInjector abstract fun objective7Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective7
@ContributesAndroidInjector abstract fun objective9Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective9
@ContributesAndroidInjector abstract fun objective10Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective10
}

View file

@ -1,25 +1,28 @@
package info.nightscout.plugins.support.di
package info.nightscout.plugins.constraints.di
import dagger.Binds
import dagger.Module
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
import info.nightscout.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin
import info.nightscout.plugins.constraints.versionChecker.VersionCheckerUtilsImpl
@Module(
includes = [
PluginsSupportModule.Bindings::class
PluginsConstraintsModule.Bindings::class,
ObjectivesModule::class
]
)
@Suppress("unused")
abstract class PluginsSupportModule {
abstract class PluginsConstraintsModule {
@Module
interface Bindings {
@Binds fun bindProcessedDeviceStatusData(versionCheckerUtils: VersionCheckerUtilsImpl): VersionCheckerUtils
@Binds fun bindBgQualityCheck(bgQualityCheck: BgQualityCheckPlugin): BgQualityCheck
@Binds fun bindsConstraints(constraintsImpl: info.nightscout.plugins.constraints.ConstraintsImpl): Constraints
}
}

Some files were not shown because too many files have changed in this diff Show more