Merge branch 'dev' into smoothing

This commit is contained in:
Milos Kozak 2022-12-09 15:08:36 +01:00 committed by GitHub
commit 0c176102cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
110 changed files with 578 additions and 504 deletions

View file

@ -198,6 +198,7 @@ dependencies {
implementation project(':plugins:automation') implementation project(':plugins:automation')
implementation project(':plugins:configuration') implementation project(':plugins:configuration')
implementation project(':plugins:constraints') implementation project(':plugins:constraints')
implementation project(':plugins:insulin')
implementation project(':plugins:main') implementation project(':plugins:main')
implementation project(':plugins:openhumans') implementation project(':plugins:openhumans')
implementation project(':plugins:sensitivity') implementation project(':plugins:sensitivity')

View file

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

View file

@ -28,6 +28,7 @@ import info.nightscout.automation.AutomationPlugin
import info.nightscout.configuration.maintenance.MaintenancePlugin import info.nightscout.configuration.maintenance.MaintenancePlugin
import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.implementation.plugin.PluginStore import info.nightscout.implementation.plugin.PluginStore
import info.nightscout.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginBase
@ -47,7 +48,6 @@ import info.nightscout.plugins.general.autotune.AutotunePlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.wear.WearPlugin import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.plugins.source.AidexPlugin import info.nightscout.plugins.source.AidexPlugin
import info.nightscout.plugins.source.DexcomPlugin import info.nightscout.plugins.source.DexcomPlugin

View file

@ -20,6 +20,7 @@ import info.nightscout.core.di.CoreModule
import info.nightscout.core.validators.di.ValidatorsModule import info.nightscout.core.validators.di.ValidatorsModule
import info.nightscout.database.impl.DatabaseModule import info.nightscout.database.impl.DatabaseModule
import info.nightscout.implementation.di.ImplementationModule import info.nightscout.implementation.di.ImplementationModule
import info.nightscout.insulin.di.InsulinModule
import info.nightscout.plugins.aps.di.ApsModule import info.nightscout.plugins.aps.di.ApsModule
import info.nightscout.plugins.constraints.di.PluginsConstraintsModule import info.nightscout.plugins.constraints.di.PluginsConstraintsModule
import info.nightscout.plugins.di.PluginsModule import info.nightscout.plugins.di.PluginsModule
@ -55,6 +56,7 @@ import javax.inject.Singleton
CoreModule::class, CoreModule::class,
DatabaseModule::class, DatabaseModule::class,
ImplementationModule::class, ImplementationModule::class,
InsulinModule::class,
OpenHumansModule::class, OpenHumansModule::class,
PluginsModule::class, PluginsModule::class,
RxModule::class, RxModule::class,

View file

@ -16,6 +16,10 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugi
import info.nightscout.automation.AutomationPlugin import info.nightscout.automation.AutomationPlugin
import info.nightscout.configuration.configBuilder.ConfigBuilderPlugin import info.nightscout.configuration.configBuilder.ConfigBuilderPlugin
import info.nightscout.configuration.maintenance.MaintenancePlugin 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.interfaces.plugin.PluginBase
import info.nightscout.plugins.aps.loop.LoopPlugin import info.nightscout.plugins.aps.loop.LoopPlugin
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
@ -35,10 +39,6 @@ import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
import info.nightscout.plugins.general.wear.WearPlugin import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin 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.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.plugins.profile.ProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin

View file

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

View file

@ -79,7 +79,6 @@
<string name="authorizationfailed">Authorization failed</string> <string name="authorizationfailed">Authorization failed</string>
<string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</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="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="fabric_upload_disabled">Crash logs upload disabled!</string>
<string name="clear_filter">Clear filter</string> <string name="clear_filter">Clear filter</string>
<string name="cannula">Cannula</string> <string name="cannula">Cannula</string>

View file

@ -1,4 +1,4 @@
package info.nightscout.plugins.insulin package info.nightscout.core.graph
import android.content.Context import android.content.Context
import android.graphics.Color 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

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

View file

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

View file

@ -57,4 +57,6 @@ interface Loop {
runningConfiguration: RunningConfiguration, runningConfiguration: RunningConfiguration,
version: String version: String
): DeviceStatus? ): DeviceStatus?
fun provideEmptyAPSResultObject(): APSResult
} }

View file

@ -1,6 +1,36 @@
package info.nightscout.interfaces.automation package info.nightscout.interfaces.automation
interface Automation { interface Automation {
fun userEvents(): List<AutomationEvent> fun userEvents(): List<AutomationEvent>
fun processEvent(someEvent: 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

@ -104,4 +104,6 @@ interface IobCobCalculator {
* @return IobTotal * @return IobTotal
*/ */
fun calculateIobFromTempBasalsIncludingConvertedExtended(): IobTotal fun calculateIobFromTempBasalsIncludingConvertedExtended(): IobTotal
fun provideEmptyAutosensDataObject(): AutosensData
} }

View file

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

View file

@ -2,8 +2,6 @@ package info.nightscout.core.di
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector 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.BolusWizard
import info.nightscout.core.wizard.QuickWizardEntry import info.nightscout.core.wizard.QuickWizardEntry
import info.nightscout.interfaces.pump.PumpEnactResult import info.nightscout.interfaces.pump.PumpEnactResult
@ -13,8 +11,6 @@ import info.nightscout.interfaces.pump.PumpEnactResult
abstract class CoreDataClassesModule { abstract class CoreDataClassesModule {
@ContributesAndroidInjector abstract fun pumpEnactResultInjector(): PumpEnactResult @ContributesAndroidInjector abstract fun pumpEnactResultInjector(): PumpEnactResult
@ContributesAndroidInjector abstract fun apsResultInjector(): APSResultObject
@ContributesAndroidInjector abstract fun autosensDataInjector(): AutosensDataObject
@ContributesAndroidInjector abstract fun bolusWizardInjector(): BolusWizard @ContributesAndroidInjector abstract fun bolusWizardInjector(): BolusWizard
@ContributesAndroidInjector abstract fun quickWizardEntryInjector(): QuickWizardEntry @ContributesAndroidInjector abstract fun quickWizardEntryInjector(): QuickWizardEntry
} }

View file

@ -5,14 +5,11 @@ import android.os.Build
import android.telephony.SmsManager import android.telephony.SmsManager
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.android.ContributesAndroidInjector
import info.nightscout.core.services.AlarmSoundService
@Module( @Module(
includes = [ includes = [
CoreDataClassesModule::class, CoreDataClassesModule::class,
PreferencesModule::class, PreferencesModule::class
ServicesModule::class
] ]
) )
open class CoreModule { 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.Action
import info.nightscout.database.entities.UserEntry.Sources import info.nightscout.database.entities.UserEntry.Sources
import info.nightscout.database.entities.ValueWithUnit 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.Config
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.automation.Automation
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.db.PersistenceLayer
@ -69,8 +68,7 @@ class BolusWizard @Inject constructor(
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: Config @Inject lateinit var config: Config
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var carbTimer: CarbTimer @Inject lateinit var automation: Automation
@Inject lateinit var bolusTimer: BolusTimer
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider @Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
@Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var persistenceLayer: PersistenceLayer @Inject lateinit var persistenceLayer: PersistenceLayer
@ -361,9 +359,9 @@ class BolusWizard @Inject constructor(
} }
accepted = true accepted = true
if (calculatedTotalInsulin > 0.0) if (calculatedTotalInsulin > 0.0)
bolusTimer.removeAutomationEventBolusReminder() automation.removeAutomationEventBolusReminder()
if (carbs > 0.0) 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) 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), 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) }, { bolusAdvisorProcessing(ctx) },
@ -402,7 +400,7 @@ class BolusWizard @Inject constructor(
if (!result.success) { if (!result.success) {
uiInteraction.runAlarm(result.comment, rh.gs(info.nightscout.core.ui.R.string.treatmentdeliveryerror), info.nightscout.core.ui.R.raw.boluserror) uiInteraction.runAlarm(result.comment, rh.gs(info.nightscout.core.ui.R.string.treatmentdeliveryerror), info.nightscout.core.ui.R.raw.boluserror)
} else } else
carbTimer.scheduleAutomationEventEatReminder() automation.scheduleAutomationEventEatReminder()
} }
}) })
} }
@ -494,7 +492,7 @@ class BolusWizard @Inject constructor(
bolusCalculatorResult?.let { persistenceLayer.insertOrUpdate(it) } bolusCalculatorResult?.let { persistenceLayer.insertOrUpdate(it) }
} }
if (useAlarm && carbs > 0 && carbTime > 0) { if (useAlarm && carbs > 0 && carbTime > 0) {
carbTimer.scheduleTimeToEatReminder(T.mins(carbTime.toLong()).secs().toInt()) automation.scheduleTimeToEatReminder(T.mins(carbTime.toLong()).secs().toInt())
} }
} }
}) })

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

@ -11,16 +11,18 @@ files:
translation: /plugins/aps/src/main/res/values-%android_code%/strings.xml translation: /plugins/aps/src/main/res/values-%android_code%/strings.xml
- source: /plugins/main/src/main/res/values/strings.xml - source: /plugins/main/src/main/res/values/strings.xml
translation: /plugins/main/src/main/res/values-%android_code%/strings.xml translation: /plugins/main/src/main/res/values-%android_code%/strings.xml
- source: /plugins/main/src/main/res/values/exam.xml - source: /plugins/constraints/src/main/res/values/exam.xml
translation: /plugins/main/src/main/res/values-%android_code%/%original_file_name% translation: /plugins/constraints/src/main/res/values-%android_code%/%original_file_name%
- source: /plugins/main/src/main/res/values/objectives.xml - source: /plugins/constraints/src/main/res/values/objectives.xml
translation: /plugins/main/src/main/res/values-%android_code%/%original_file_name% translation: /plugins/constraints/src/main/res/values-%android_code%/%original_file_name%
- source: /plugins/automation/src/main/res/values/strings.xml - source: /plugins/automation/src/main/res/values/strings.xml
translation: /plugins/automation/src/main/res/values-%android_code%/strings.xml translation: /plugins/automation/src/main/res/values-%android_code%/strings.xml
- source: /plugins/openhumans/src/main/res/values/strings.xml - source: /plugins/openhumans/src/main/res/values/strings.xml
translation: /plugins/openhumans/src/main/res/values-%android_code%/strings.xml translation: /plugins/openhumans/src/main/res/values-%android_code%/strings.xml
- source: /plugins/sensitivity/src/main/res/values/strings.xml - source: /plugins/sensitivity/src/main/res/values/strings.xml
translation: /plugins/sensitivity/src/main/res/values-%android_code%/strings.xml translation: /plugins/sensitivity/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 - source: /plugins/configuration/src/main/res/values/strings.xml
translation: /plugins/configuration/src/main/res/values-%android_code%/strings.xml translation: /plugins/configuration/src/main/res/values-%android_code%/strings.xml
- source: /plugins/sync/src/main/res/values/strings.xml - source: /plugins/sync/src/main/res/values/strings.xml

View file

@ -19,14 +19,12 @@ dependencies {
implementation project(':app-wear-shared:shared') implementation project(':app-wear-shared:shared')
implementation project(':database:entities') implementation project(':database:entities')
implementation project(':database:impl') implementation project(':database:impl')
implementation project(':plugins:automation')
implementation project(':core:main') implementation project(':core:main')
implementation project(':core:graph') implementation project(':core:graph')
implementation project(':core:graphview') implementation project(':core:graphview')
implementation project(':core:interfaces') implementation project(':core:interfaces')
implementation project(':core:ui') implementation project(':core:ui')
implementation project(':core:utils') implementation project(':core:utils')
implementation project(':ui')
// Protection // Protection
api 'androidx.biometric:biometric:1.1.0' 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.TemporaryTarget
import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.entities.TherapyEvent
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventEffectiveProfileSwitchChanged import info.nightscout.rx.events.EventEffectiveProfileSwitchChanged
import info.nightscout.rx.events.EventExtendedBolusChange 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.events.EventTreatmentChange
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.ui.widget.Widget
import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.disposables.Disposable
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class CompatDBHelper @Inject constructor( class CompatDBHelper @Inject constructor(
val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
val repository: AppRepository, private val repository: AppRepository,
val rxBus: RxBus, private val rxBus: RxBus,
val context: Context private val context: Context,
private val uiInteraction: UiInteraction
) { ) {
fun dbChangeDisposable(): Disposable = repository fun dbChangeDisposable(): Disposable = repository
.changeObservable() .changeObservable()
.doOnSubscribe { .doOnSubscribe {
rxBus.send(EventNewBG(null)) rxBus.send(EventNewBG(null))
Widget.updateWidget(context) uiInteraction.updateWidget(context)
} }
.subscribe { .subscribe {
/** /**
@ -57,7 +58,7 @@ class CompatDBHelper @Inject constructor(
it.filterIsInstance<GlucoseValue>().maxByOrNull { gv -> gv.timestamp }?.let { gv -> it.filterIsInstance<GlucoseValue>().maxByOrNull { gv -> gv.timestamp }?.let { gv ->
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg $gv") aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg $gv")
rxBus.send(EventNewBG(gv.timestamp)) rxBus.send(EventNewBG(gv.timestamp))
Widget.updateWidget(context) uiInteraction.updateWidget(context)
newestGlucoseValue = gv newestGlucoseValue = gv
} }
it.filterIsInstance<GlucoseValue>().minOfOrNull { gv -> gv.timestamp }?.let { timestamp -> it.filterIsInstance<GlucoseValue>().minOfOrNull { gv -> gv.timestamp }?.let { timestamp ->

View file

@ -4,8 +4,6 @@ import dagger.Binds
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import info.nightscout.core.graph.OverviewData 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.DefaultValueHelperImpl
import info.nightscout.implementation.HardLimitsImpl import info.nightscout.implementation.HardLimitsImpl
import info.nightscout.implementation.LocalAlertUtilsImpl import info.nightscout.implementation.LocalAlertUtilsImpl
@ -40,8 +38,6 @@ import info.nightscout.implementation.stats.TddCalculatorImpl
import info.nightscout.implementation.stats.TirCalculatorImpl import info.nightscout.implementation.stats.TirCalculatorImpl
import info.nightscout.implementation.storage.FileStorage import info.nightscout.implementation.storage.FileStorage
import info.nightscout.implementation.userEntry.UserEntryPresentationHelperImpl 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.LocalAlertUtils
import info.nightscout.interfaces.NotificationHolder import info.nightscout.interfaces.NotificationHolder
import info.nightscout.interfaces.Translator import info.nightscout.interfaces.Translator
@ -113,8 +109,6 @@ abstract class ImplementationModule {
@Binds fun bindDexcomTirCalculatorInterface(dexcomTirCalculator: DexcomTirCalculatorImpl): DexcomTirCalculator @Binds fun bindDexcomTirCalculatorInterface(dexcomTirCalculator: DexcomTirCalculatorImpl): DexcomTirCalculator
@Binds fun bindPumpSyncInterface(pumpSyncImplementation: PumpSyncImplementation): PumpSync @Binds fun bindPumpSyncInterface(pumpSyncImplementation: PumpSyncImplementation): PumpSync
@Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast @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 bindLocalAlertUtilsInterface(localAlertUtils: LocalAlertUtilsImpl): LocalAlertUtils
@Binds fun bindIconsProviderInterface(iconsProvider: IconsProviderImplementation): IconsProvider @Binds fun bindIconsProviderInterface(iconsProvider: IconsProviderImplementation): IconsProvider
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder @Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder

View file

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

View file

@ -5,8 +5,6 @@
<string name="bg_label">BG</string> <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="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="basal_value_below_minimum">Basal value below minimum. Profile not set!</string>
<string name="permission">Permission</string> <string name="permission">Permission</string>

View file

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

View file

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

View file

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

View file

@ -57,6 +57,7 @@ import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.interfaces.receivers.ReceiverStatusStore import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.plugins.aps.R import info.nightscout.plugins.aps.R
import info.nightscout.plugins.aps.loop.events.EventLoopSetLastRunGui import info.nightscout.plugins.aps.loop.events.EventLoopSetLastRunGui
import info.nightscout.plugins.aps.loop.extensions.json import info.nightscout.plugins.aps.loop.extensions.json
@ -782,6 +783,9 @@ class LoopPlugin @Inject constructor(
configuration = runningConfiguration.configuration().toString() configuration = runningConfiguration.configuration().toString()
) )
} }
override fun provideEmptyAPSResultObject(): APSResult = APSResultObject(injector)
companion object { companion object {
private const val CHANNEL_ID = "AAPS-OpenLoop" private const val CHANNEL_ID = "AAPS-OpenLoop"

View file

@ -1,7 +1,7 @@
package info.nightscout.plugins.aps.openAPSAMA package info.nightscout.plugins.aps.openAPSAMA
import dagger.android.HasAndroidInjector 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.convertedToAbsolute
import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.core.extensions.plannedRemainingMinutes import info.nightscout.core.extensions.plannedRemainingMinutes

View file

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

View file

@ -1,7 +1,7 @@
package info.nightscout.plugins.aps.openAPSSMB package info.nightscout.plugins.aps.openAPSSMB
import dagger.android.HasAndroidInjector 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.convertedToAbsolute
import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes
import info.nightscout.core.extensions.plannedRemainingMinutes import info.nightscout.core.extensions.plannedRemainingMinutes

View file

@ -1,7 +1,7 @@
package info.nightscout.plugins.aps.openAPSSMB package info.nightscout.plugins.aps.openAPSSMB
import dagger.android.HasAndroidInjector 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.interfaces.aps.VariableSensitivityResult
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import org.json.JSONException import org.json.JSONException

View file

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

View file

@ -28,6 +28,7 @@ dependencies {
implementation project(':core:interfaces') implementation project(':core:interfaces')
testImplementation project(':implementation') testImplementation project(':implementation')
testImplementation project(':plugins:main')
api "androidx.constraintlayout:constraintlayout:$constraintlayout_version" api "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
api "com.google.android.gms:play-services-location:$play_services_location_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.ActionStartTempTarget
import info.nightscout.automation.actions.ActionStopProcessing import info.nightscout.automation.actions.ActionStopProcessing
import info.nightscout.automation.actions.ActionStopTempTarget 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.EventAutomationDataChanged
import info.nightscout.automation.events.EventAutomationUpdateGui import info.nightscout.automation.events.EventAutomationUpdateGui
import info.nightscout.automation.events.EventLocationChange 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.automation.triggers.TriggerWifiSsid
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.automation.Automation import info.nightscout.interfaces.automation.Automation
import info.nightscout.interfaces.automation.AutomationEvent 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.PluginDescription
import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.queue.Callback import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.utils.TimerUtil
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventBTChange import info.nightscout.rx.events.EventBTChange
@ -67,6 +71,7 @@ import io.reactivex.rxjava3.kotlin.plusAssign
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import java.text.DecimalFormat
import java.util.Collections import java.util.Collections
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -87,7 +92,8 @@ class AutomationPlugin @Inject constructor(
private val config: Config, private val config: Config,
private val locationServiceHelper: LocationServiceHelper, private val locationServiceHelper: LocationServiceHelper,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val activePlugin: ActivePlugin private val activePlugin: ActivePlugin,
private val timerUtil: TimerUtil
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
@ -402,4 +408,109 @@ class AutomationPlugin @Inject constructor(
TriggerBTDevice(injector), 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="saturday_short">S</string>
<string name="sunday_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> </resources>

View file

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

View file

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

View file

@ -10,6 +10,7 @@ import info.nightscout.database.entities.DeviceStatus
import info.nightscout.database.entities.OfflineEvent import info.nightscout.database.entities.OfflineEvent
import info.nightscout.interfaces.ConfigBuilder import info.nightscout.interfaces.ConfigBuilder
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.configBuilder.RunningConfiguration import info.nightscout.interfaces.configBuilder.RunningConfiguration
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
@ -42,7 +43,8 @@ ActionsTestBase : TestBaseWithProfile() {
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
rh: ResourceHelper, rh: ResourceHelper,
injector: HasAndroidInjector, injector: HasAndroidInjector,
pluginDescription: PluginDescription pluginDescription: PluginDescription,
private val apsResult: APSResult
) : PluginBase( ) : PluginBase(
pluginDescription, aapsLogger, rh, injector pluginDescription, aapsLogger, rh, injector
), Loop { ), Loop {
@ -75,6 +77,9 @@ ActionsTestBase : TestBaseWithProfile() {
runningConfiguration: RunningConfiguration, runningConfiguration: RunningConfiguration,
version: String version: String
): DeviceStatus? = null ): DeviceStatus? = null
override fun provideEmptyAPSResultObject(): APSResult = apsResult
override fun setPluginEnabled(type: PluginType, newState: Boolean) {} override fun setPluginEnabled(type: PluginType, newState: Boolean) {}
} }
@ -87,6 +92,7 @@ ActionsTestBase : TestBaseWithProfile() {
@Mock lateinit var loopPlugin: TestLoopPlugin @Mock lateinit var loopPlugin: TestLoopPlugin
@Mock lateinit var uel: UserEntryLogger @Mock lateinit var uel: UserEntryLogger
@Mock lateinit var context: Context @Mock lateinit var context: Context
@Mock lateinit var apsResult: APSResult
private val pluginDescription = PluginDescription() private val pluginDescription = PluginDescription()
lateinit var testPumpPlugin: TestPumpPlugin lateinit var testPumpPlugin: TestPumpPlugin

View file

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

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

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,28 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-kapt'
id 'kotlin-allopen'
id 'com.hiya.jacoco-android'
}
apply from: "${project.rootDir}/core/main/android_dependencies.gradle"
apply from: "${project.rootDir}/core/main/android_module_dependencies.gradle"
apply from: "${project.rootDir}/core/main/allopen_dependencies.gradle"
apply from: "${project.rootDir}/core/main/test_dependencies.gradle"
apply from: "${project.rootDir}/core/main/jacoco_global.gradle"
android {
namespace 'info.nightscout.insulin'
}
dependencies {
implementation project(':app-wear-shared:shared')
implementation project(':core:graph')
implementation project(':core:graphview')
implementation project(':core:interfaces')
implementation project(':core:ui')
implementation project(':core:utils')
implementation project(':core:validators')
implementation project(':database:entities')
}

View file

21
plugins/insulin/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

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

View file

@ -1,12 +1,12 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.insulin.databinding.InsulinFragmentBinding
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.plugins.databinding.InsulinFragmentBinding
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import javax.inject.Inject import javax.inject.Inject

View file

@ -1,11 +1,11 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@ -21,8 +21,9 @@ class InsulinLyumjevPlugin @Inject constructor(
rxBus: RxBus, rxBus: RxBus,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
config: Config, config: Config,
hardLimits: HardLimits hardLimits: HardLimits,
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) { uiInteraction: UiInteraction
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction) {
override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_LYUMJEV override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_LYUMJEV
override val friendlyName get(): String = rh.gs(R.string.lyumjev) override val friendlyName get(): String = rh.gs(R.string.lyumjev)

View file

@ -1,7 +1,6 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.core.events.EventNewNotification
import info.nightscout.database.entities.Bolus import info.nightscout.database.entities.Bolus
import info.nightscout.database.entities.embedments.InsulinConfiguration import info.nightscout.database.entities.embedments.InsulinConfiguration
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
@ -12,8 +11,8 @@ import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@ -34,7 +33,8 @@ abstract class InsulinOrefBasePlugin(
val rxBus: RxBus, val rxBus: RxBus,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
config: Config, config: Config,
val hardLimits: HardLimits val hardLimits: HardLimits,
val uiInteraction: UiInteraction
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.INSULIN) .mainType(PluginType.INSULIN)
@ -61,8 +61,7 @@ abstract class InsulinOrefBasePlugin(
open fun sendShortDiaNotification(dia: Double) { open fun sendShortDiaNotification(dia: Double) {
if (System.currentTimeMillis() - lastWarned > 60 * 1000) { if (System.currentTimeMillis() - lastWarned > 60 * 1000) {
lastWarned = System.currentTimeMillis() lastWarned = System.currentTimeMillis()
val notification = Notification(Notification.SHORT_DIA, String.format(notificationPattern, dia, hardLimits.minDia()), Notification.URGENT) uiInteraction.addNotification(Notification.SHORT_DIA, String.format(notificationPattern, dia, hardLimits.minDia()), Notification.URGENT)
rxBus.send(EventNewNotification(notification))
} }
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.putInt import info.nightscout.core.extensions.putInt
@ -6,8 +6,8 @@ import info.nightscout.core.extensions.storeInt
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@ -28,16 +28,17 @@ class InsulinOrefFreePeakPlugin @Inject constructor(
rxBus: RxBus, rxBus: RxBus,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
config: Config, config: Config,
hardLimits: HardLimits hardLimits: HardLimits,
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) { uiInteraction: UiInteraction
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction) {
override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_FREE_PEAK override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_FREE_PEAK
override val friendlyName get(): String = rh.gs(R.string.free_peak_oref) override val friendlyName get(): String = rh.gs(R.string.free_peak_oref)
override fun configuration(): JSONObject = JSONObject().putInt(R.string.key_insulin_oref_peak, sp, rh) override fun configuration(): JSONObject = JSONObject().putInt(info.nightscout.core.utils.R.string.key_insulin_oref_peak, sp, rh)
override fun applyConfiguration(configuration: JSONObject) { override fun applyConfiguration(configuration: JSONObject) {
configuration.storeInt(R.string.key_insulin_oref_peak, sp, rh) configuration.storeInt(info.nightscout.core.utils.R.string.key_insulin_oref_peak, sp, rh)
} }
override fun commentStandardText(): String { override fun commentStandardText(): String {
@ -45,7 +46,7 @@ class InsulinOrefFreePeakPlugin @Inject constructor(
} }
override val peak: Int override val peak: Int
get() = sp.getInt(R.string.key_insulin_oref_peak, DEFAULT_PEAK) get() = sp.getInt(info.nightscout.core.utils.R.string.key_insulin_oref_peak, DEFAULT_PEAK)
companion object { companion object {

View file

@ -1,11 +1,11 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@ -24,8 +24,9 @@ class InsulinOrefRapidActingPlugin @Inject constructor(
rxBus: RxBus, rxBus: RxBus,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
config: Config, config: Config,
hardLimits: HardLimits hardLimits: HardLimits,
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) { uiInteraction: UiInteraction
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction) {
override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_RAPID_ACTING override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_RAPID_ACTING
override val friendlyName get(): String = rh.gs(R.string.rapid_acting_oref) override val friendlyName get(): String = rh.gs(R.string.rapid_acting_oref)

View file

@ -1,11 +1,11 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@ -24,8 +24,9 @@ class InsulinOrefUltraRapidActingPlugin @Inject constructor(
rxBus: RxBus, rxBus: RxBus,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
config: Config, config: Config,
hardLimits: HardLimits hardLimits: HardLimits,
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) { uiInteraction: UiInteraction
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction) {
override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_ULTRA_RAPID_ACTING override val id get(): Insulin.InsulinType = Insulin.InsulinType.OREF_ULTRA_RAPID_ACTING
override val friendlyName get(): String = rh.gs(R.string.ultra_rapid_oref) override val friendlyName get(): String = rh.gs(R.string.ultra_rapid_oref)

View file

@ -1,8 +1,8 @@
package info.nightscout.plugins.di package info.nightscout.insulin.di
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import info.nightscout.plugins.insulin.InsulinFragment import info.nightscout.insulin.InsulinFragment
@Module @Module
@Suppress("unused") @Suppress("unused")

View file

@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".insulin.InsulinFragment"> tools:context="info.nightscout.insulin.InsulinFragment">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -30,7 +30,7 @@
android:layout_margin="10dp" android:layout_margin="10dp"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<info.nightscout.plugins.insulin.ActivityGraph <info.nightscout.core.graph.ActivityGraph
android:id="@+id/graph" android:id="@+id/graph"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="200dip" android:layout_height="200dip"

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Insulin -->
<string name="key_insulin_oref_peak_settings" translatable="false">insulin_oref_peak_settings</string>
<string name="lyumjev">Lyumjev</string>
<string name="description_insulin_rapid">Insulin preset for Humalog and NovoRapid / NovoLog</string>
<string name="description_insulin_ultra_rapid">Insulin preset for Fiasp</string>
<string name="description_insulin_lyumjev">Insulin preset for Lyumjev</string>
<string name="description_insulin_free_peak">Allows you to define the peak of the insulin activity and should only be used by advanced users</string>
<string name="insulin_shortname">INS</string>
<string name="insulin_oref_peak">IOB Curve Peak Time</string>
<string name="insulin_peak_time">Peak Time [min]</string>
<string name="free_peak_oref">Free-Peak Oref</string>
<string name="rapid_acting_oref">Rapid-Acting Oref</string>
<string name="ultra_rapid_oref">Ultra-Rapid Oref</string>
<string name="dia_too_short">DIA of %1$f too short - using %2$f instead!</string>
<string name="fast_acting_insulin_comment">Novorapid, Novolog, Humalog</string>
<string name="ultra_fast_acting_insulin_comment">Fiasp</string>
</resources>

View file

@ -0,0 +1,37 @@
package info.nightscout.androidaps
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.TestAapsSchedulers
import info.nightscout.rx.logging.AAPSLoggerTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mockito
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.junit.jupiter.MockitoSettings
import org.mockito.quality.Strictness
import java.util.Locale
@ExtendWith(MockitoExtension::class)
@MockitoSettings(strictness = Strictness.LENIENT)
open class TestBase {
val aapsLogger = AAPSLoggerTest()
val aapsSchedulers: AapsSchedulers = TestAapsSchedulers()
@BeforeEach
fun setupLocale() {
Locale.setDefault(Locale.ENGLISH)
System.setProperty("disableFirebase", "true")
}
// Workaround for Kotlin nullability.
// https://medium.com/@elye.project/befriending-kotlin-and-mockito-1c2e7b0ef791
// https://stackoverflow.com/questions/30305217/is-it-possible-to-use-mockito-in-kotlin
fun <T> anyObject(): T {
Mockito.any<T>()
return uninitialized()
}
@Suppress("Unchecked_Cast")
fun <T> uninitialized(): T = null as T
}

View file

@ -1,16 +1,16 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import org.junit.Assert.assertEquals import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.ExtendWith
@ -33,6 +33,7 @@ class InsulinLyumjevPluginTest {
@Mock lateinit var aapsLogger: AAPSLogger @Mock lateinit var aapsLogger: AAPSLogger
@Mock lateinit var config: Config @Mock lateinit var config: Config
@Mock lateinit var hardLimits: HardLimits @Mock lateinit var hardLimits: HardLimits
@Mock lateinit var uiInteraction: UiInteraction
private var injector: HasAndroidInjector = HasAndroidInjector { private var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
@ -41,29 +42,29 @@ class InsulinLyumjevPluginTest {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
sut = InsulinLyumjevPlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) sut = InsulinLyumjevPlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction)
} }
@Test @Test
fun `simple peak test`() { fun `simple peak test`() {
assertEquals(45, sut.peak) Assertions.assertEquals(45, sut.peak)
} }
@Test @Test
fun getIdTest() { fun getIdTest() {
assertEquals(Insulin.InsulinType.OREF_LYUMJEV, sut.id) Assertions.assertEquals(Insulin.InsulinType.OREF_LYUMJEV, sut.id)
} }
@Test @Test
fun commentStandardTextTest() { fun commentStandardTextTest() {
`when`(rh.gs(eq(R.string.lyumjev))).thenReturn("Lyumjev") `when`(rh.gs(eq(R.string.lyumjev))).thenReturn("Lyumjev")
assertEquals("Lyumjev", sut.commentStandardText()) Assertions.assertEquals("Lyumjev", sut.commentStandardText())
} }
@Test @Test
fun getFriendlyNameTest() { fun getFriendlyNameTest() {
`when`(rh.gs(eq(R.string.lyumjev))).thenReturn("Lyumjev") `when`(rh.gs(eq(R.string.lyumjev))).thenReturn("Lyumjev")
assertEquals("Lyumjev", sut.friendlyName) Assertions.assertEquals("Lyumjev", sut.friendlyName)
} }
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
@ -7,12 +7,13 @@ import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import org.json.JSONObject 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.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.ExtendWith
@ -38,7 +39,7 @@ class InsulinOrefBasePluginTest {
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
config: Config, config: Config,
hardLimits: HardLimits hardLimits: HardLimits
) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) { ) : InsulinOrefBasePlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction) {
override fun sendShortDiaNotification(dia: Double) { override fun sendShortDiaNotification(dia: Double) {
shortDiaNotificationSend = true shortDiaNotificationSend = true
@ -65,6 +66,7 @@ class InsulinOrefBasePluginTest {
@Mock lateinit var aapsLogger: AAPSLogger @Mock lateinit var aapsLogger: AAPSLogger
@Mock lateinit var config: Config @Mock lateinit var config: Config
@Mock lateinit var hardLimits: HardLimits @Mock lateinit var hardLimits: HardLimits
@Mock lateinit var uiInteraction: UiInteraction
private var injector: HasAndroidInjector = HasAndroidInjector { private var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
@ -79,12 +81,12 @@ class InsulinOrefBasePluginTest {
@Test @Test
fun testGetDia() { fun testGetDia() {
Assert.assertEquals(5.0, sut.dia, 0.0) Assertions.assertEquals(5.0, sut.dia, 0.0)
testUserDefinedDia = 5.0 + 1 testUserDefinedDia = 5.0 + 1
Assert.assertEquals(5.0 + 1, sut.dia, 0.0) Assertions.assertEquals(5.0 + 1, sut.dia, 0.0)
testUserDefinedDia = 5.0 - 1 testUserDefinedDia = 5.0 - 1
Assert.assertEquals(5.0, sut.dia, 0.0) Assertions.assertEquals(5.0, sut.dia, 0.0)
Assert.assertTrue(shortDiaNotificationSend) Assertions.assertTrue(shortDiaNotificationSend)
} }
@Test @Test
@ -96,22 +98,22 @@ class InsulinOrefBasePluginTest {
// check directly after bolus // check directly after bolus
treatment.timestamp = time treatment.timestamp = time
treatment.amount = 10.0 treatment.amount = 10.0
Assert.assertEquals(10.0, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1) Assertions.assertEquals(10.0, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1)
// check after 1 hour // check after 1 hour
treatment.timestamp = time - 1 * 60 * 60 * 1000 // 1 hour treatment.timestamp = time - 1 * 60 * 60 * 1000 // 1 hour
treatment.amount = 10.0 treatment.amount = 10.0
Assert.assertEquals(3.92, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1) Assertions.assertEquals(3.92, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1)
// check after 2 hour // check after 2 hour
treatment.timestamp = time - 2 * 60 * 60 * 1000 // 2 hours treatment.timestamp = time - 2 * 60 * 60 * 1000 // 2 hours
treatment.amount = 10.0 treatment.amount = 10.0
Assert.assertEquals(0.77, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1) Assertions.assertEquals(0.77, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1)
// check after 3 hour // check after 3 hour
treatment.timestamp = time - 3 * 60 * 60 * 1000 // 3 hours treatment.timestamp = time - 3 * 60 * 60 * 1000 // 3 hours
treatment.amount = 10.0 treatment.amount = 10.0
Assert.assertEquals(0.10, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1) Assertions.assertEquals(0.10, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1)
// check after dia // check after dia
treatment.timestamp = time - 4 * 60 * 60 * 1000 // 4 hours treatment.timestamp = time - 4 * 60 * 60 * 1000 // 4 hours
treatment.amount = 10.0 treatment.amount = 10.0
Assert.assertEquals(0.0, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1) Assertions.assertEquals(0.0, sut.iobCalcForTreatment(treatment, time, Constants.defaultDIA).iobContrib, 0.1)
} }
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
@ -6,12 +6,12 @@ import info.nightscout.androidaps.TestBase
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert.assertEquals import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyInt
@ -33,6 +33,7 @@ class InsulinOrefFreePeakPluginTest : TestBase() {
@Mock lateinit var profileFunction: ProfileFunction @Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var config: Config @Mock lateinit var config: Config
@Mock lateinit var hardLimits: HardLimits @Mock lateinit var hardLimits: HardLimits
@Mock lateinit var uiInteraction: UiInteraction
private var injector: HasAndroidInjector = HasAndroidInjector { private var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
@ -41,30 +42,30 @@ class InsulinOrefFreePeakPluginTest : TestBase() {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
sut = InsulinOrefFreePeakPlugin(injector, sp, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) sut = InsulinOrefFreePeakPlugin(injector, sp, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction)
} }
@Test @Test
fun `simple peak test`() { fun `simple peak test`() {
`when`(sp.getInt(eq(R.string.key_insulin_oref_peak), anyInt())).thenReturn(90) `when`(sp.getInt(eq(info.nightscout.core.utils.R.string.key_insulin_oref_peak), anyInt())).thenReturn(90)
assertEquals(90, sut.peak) Assertions.assertEquals(90, sut.peak)
} }
@Test @Test
fun getIdTest() { fun getIdTest() {
assertEquals(Insulin.InsulinType.OREF_FREE_PEAK, sut.id) Assertions.assertEquals(Insulin.InsulinType.OREF_FREE_PEAK, sut.id)
} }
@Test @Test
fun commentStandardTextTest() { fun commentStandardTextTest() {
`when`(sp.getInt(eq(R.string.key_insulin_oref_peak), anyInt())).thenReturn(90) `when`(sp.getInt(eq(info.nightscout.core.utils.R.string.key_insulin_oref_peak), anyInt())).thenReturn(90)
`when`(rh.gs(eq(R.string.insulin_peak_time))).thenReturn("Peak Time [min]") `when`(rh.gs(eq(R.string.insulin_peak_time))).thenReturn("Peak Time [min]")
assertEquals("Peak Time [min]: 90", sut.commentStandardText()) Assertions.assertEquals("Peak Time [min]: 90", sut.commentStandardText())
} }
@Test @Test
fun getFriendlyNameTest() { fun getFriendlyNameTest() {
`when`(rh.gs(eq(R.string.free_peak_oref))).thenReturn("Free-Peak Oref") `when`(rh.gs(eq(R.string.free_peak_oref))).thenReturn("Free-Peak Oref")
assertEquals("Free-Peak Oref", sut.friendlyName) Assertions.assertEquals("Free-Peak Oref", sut.friendlyName)
} }
} }

View file

@ -1,16 +1,16 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import org.junit.Assert.assertEquals import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.ExtendWith
@ -33,6 +33,7 @@ class InsulinOrefRapidActingPluginTest {
@Mock lateinit var aapsLogger: AAPSLogger @Mock lateinit var aapsLogger: AAPSLogger
@Mock lateinit var config: Config @Mock lateinit var config: Config
@Mock lateinit var hardLimits: HardLimits @Mock lateinit var hardLimits: HardLimits
@Mock lateinit var uiInteraction: UiInteraction
private var injector: HasAndroidInjector = HasAndroidInjector { private var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
@ -41,29 +42,29 @@ class InsulinOrefRapidActingPluginTest {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
sut = InsulinOrefRapidActingPlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) sut = InsulinOrefRapidActingPlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction)
} }
@Test @Test
fun `simple peak test`() { fun `simple peak test`() {
assertEquals(75, sut.peak) Assertions.assertEquals(75, sut.peak)
} }
@Test @Test
fun getIdTest() { fun getIdTest() {
assertEquals(Insulin.InsulinType.OREF_RAPID_ACTING, sut.id) Assertions.assertEquals(Insulin.InsulinType.OREF_RAPID_ACTING, sut.id)
} }
@Test @Test
fun commentStandardTextTest() { fun commentStandardTextTest() {
`when`(rh.gs(eq(R.string.fast_acting_insulin_comment))).thenReturn("Novorapid, Novolog, Humalog") `when`(rh.gs(eq(R.string.fast_acting_insulin_comment))).thenReturn("Novorapid, Novolog, Humalog")
assertEquals("Novorapid, Novolog, Humalog", sut.commentStandardText()) Assertions.assertEquals("Novorapid, Novolog, Humalog", sut.commentStandardText())
} }
@Test @Test
fun getFriendlyNameTest() { fun getFriendlyNameTest() {
`when`(rh.gs(eq(R.string.rapid_acting_oref))).thenReturn("Rapid-Acting Oref") `when`(rh.gs(eq(R.string.rapid_acting_oref))).thenReturn("Rapid-Acting Oref")
assertEquals("Rapid-Acting Oref", sut.friendlyName) Assertions.assertEquals("Rapid-Acting Oref", sut.friendlyName)
} }
} }

View file

@ -1,16 +1,16 @@
package info.nightscout.plugins.insulin package info.nightscout.insulin
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import org.junit.Assert.assertEquals import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.ExtendWith
@ -33,6 +33,7 @@ class InsulinOrefUltraRapidActingPluginTest {
@Mock lateinit var aapsLogger: AAPSLogger @Mock lateinit var aapsLogger: AAPSLogger
@Mock lateinit var config: Config @Mock lateinit var config: Config
@Mock lateinit var hardLimits: HardLimits @Mock lateinit var hardLimits: HardLimits
@Mock lateinit var uiInteraction: UiInteraction
private var injector: HasAndroidInjector = HasAndroidInjector { private var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
@ -41,29 +42,29 @@ class InsulinOrefUltraRapidActingPluginTest {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
sut = InsulinOrefUltraRapidActingPlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits) sut = InsulinOrefUltraRapidActingPlugin(injector, rh, profileFunction, rxBus, aapsLogger, config, hardLimits, uiInteraction)
} }
@Test @Test
fun `simple peak test`() { fun `simple peak test`() {
assertEquals(55, sut.peak) Assertions.assertEquals(55, sut.peak)
} }
@Test @Test
fun getIdTest() { fun getIdTest() {
assertEquals(Insulin.InsulinType.OREF_ULTRA_RAPID_ACTING, sut.id) Assertions.assertEquals(Insulin.InsulinType.OREF_ULTRA_RAPID_ACTING, sut.id)
} }
@Test @Test
fun commentStandardTextTest() { fun commentStandardTextTest() {
`when`(rh.gs(eq(R.string.ultra_fast_acting_insulin_comment))).thenReturn("Fiasp") `when`(rh.gs(eq(R.string.ultra_fast_acting_insulin_comment))).thenReturn("Fiasp")
assertEquals("Fiasp", sut.commentStandardText()) Assertions.assertEquals("Fiasp", sut.commentStandardText())
} }
@Test @Test
fun getFriendlyNameTest() { fun getFriendlyNameTest() {
`when`(rh.gs(eq(R.string.ultra_rapid_oref))).thenReturn("Ultra-Rapid Oref") `when`(rh.gs(eq(R.string.ultra_rapid_oref))).thenReturn("Ultra-Rapid Oref")
assertEquals("Ultra-Rapid Oref", sut.friendlyName) Assertions.assertEquals("Ultra-Rapid Oref", sut.friendlyName)
} }
} }

View file

@ -9,11 +9,11 @@ import info.nightscout.plugins.general.persistentNotification.DummyService
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.wear.WearFragment import info.nightscout.plugins.general.wear.WearFragment
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
@Module( @Module(
includes = [ includes = [
PluginsModule.Bindings::class, PluginsModule.Bindings::class,
InsulinModule::class,
FoodModule::class, FoodModule::class,
SMSCommunicatorModule::class, SMSCommunicatorModule::class,
ProfileModule::class, ProfileModule::class,
@ -32,6 +32,8 @@ abstract class PluginsModule {
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment @ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
@ContributesAndroidInjector abstract fun contributesDummyService(): DummyService @ContributesAndroidInjector abstract fun contributesDummyService(): DummyService
@ContributesAndroidInjector abstract fun autosensDataObjectInjector(): AutosensDataObject
@Module @Module
interface Bindings { interface Bindings {

View file

@ -909,7 +909,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val useBatteryLevel = (pump.model() == PumpType.OMNIPOD_EROS) val useBatteryLevel = (pump.model() == PumpType.OMNIPOD_EROS)
|| (pump.model() != PumpType.ACCU_CHEK_COMBO && pump.model() != PumpType.OMNIPOD_DASH) || (pump.model() != PumpType.ACCU_CHEK_COMBO && pump.model() != PumpType.OMNIPOD_DASH)
batteryLevel.visibility = useBatteryLevel.toVisibility() batteryLevel.visibility = useBatteryLevel.toVisibility()
statusLights.visibility = (sp.getBoolean(R.string.key_show_statuslights, true) || config.NSCLIENT).toVisibility() statusLightsLayout.visibility = (sp.getBoolean(R.string.key_show_statuslights, true) || config.NSCLIENT).toVisibility()
} }
statusLightHandler.updateStatusLights( statusLightHandler.updateStatusLights(
binding.statusLightsLayout.cannulaAge, binding.statusLightsLayout.cannulaAge,

View file

@ -38,6 +38,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.MidnightTime import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.plugins.R import info.nightscout.plugins.R
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataStoreObject import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataStoreObject
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -128,7 +129,7 @@ class IobCobCalculatorPlugin @Inject constructor(
event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_absorption_cutoff)) || event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_absorption_cutoff)) ||
event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_openapsama_autosens_max)) || event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_openapsama_autosens_max)) ||
event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_openapsama_autosens_min)) || event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_openapsama_autosens_min)) ||
event.isChanged(rh.gs(R.string.key_insulin_oref_peak)) event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_insulin_oref_peak))
) { ) {
resetDataAndRunCalculation("onEventPreferenceChange", event) resetDataAndRunCalculation("onEventPreferenceChange", event)
} }
@ -599,6 +600,8 @@ class IobCobCalculatorPlugin @Inject constructor(
override fun calculateIobFromTempBasalsIncludingConvertedExtended(): IobTotal = override fun calculateIobFromTempBasalsIncludingConvertedExtended(): IobTotal =
calculateIobToTimeFromTempBasalsIncludingConvertedExtended(dateUtil.now()) calculateIobToTimeFromTempBasalsIncludingConvertedExtended(dateUtil.now())
override fun provideEmptyAutosensDataObject(): AutosensData = AutosensDataObject(injector)
override fun calculateIobToTimeFromTempBasalsIncludingConvertedExtended(toTime: Long): IobTotal { override fun calculateIobToTimeFromTempBasalsIncludingConvertedExtended(toTime: Long): IobTotal {
val total = IobTotal(toTime) val total = IobTotal(toTime)
val now = dateUtil.now() val now = dateUtil.now()

View file

@ -1,4 +1,4 @@
package info.nightscout.core.iob.iobCobCalculator.data package info.nightscout.plugins.iob.iobCobCalculator.data
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
@ -22,18 +22,22 @@ class AutosensDataObject(injector: HasAndroidInjector) : AutosensData {
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
init {
injector.androidInjector().inject(this)
}
override var time = 0L override var time = 0L
override var bg = 0.0 // mgdl override var bg = 0.0 // mgdl
override var pastSensitivity = "" override var pastSensitivity = ""
override var deviation = 0.0 override var deviation = 0.0
override var validDeviation = false override var validDeviation = false
var activeCarbsList: MutableList<AutosensData.CarbsInPast> = ArrayList() override var activeCarbsList: MutableList<AutosensData.CarbsInPast> = ArrayList()
var absorbed = 0.0 override var absorbed = 0.0
override var carbsFromBolus = 0.0 override var carbsFromBolus = 0.0
override var cob = 0.0 override var cob = 0.0
var bgi = 0.0 override var bgi = 0.0
var delta = 0.0 override var delta = 0.0
var avgDelta = 0.0 override var avgDelta = 0.0
override var avgDeviation = 0.0 override var avgDeviation = 0.0
override var autosensResult = AutosensResult() override var autosensResult = AutosensResult()
override var slopeFromMaxDeviation = 0.0 override var slopeFromMaxDeviation = 0.0
@ -86,7 +90,7 @@ class AutosensDataObject(injector: HasAndroidInjector) : AutosensData {
} }
// remove carbs older than timeframe // remove carbs older than timeframe
fun removeOldCarbs(toTime: Long, isAAPSOrWeighted: Boolean) { override fun removeOldCarbs(toTime: Long, isAAPSOrWeighted: Boolean) {
val maxAbsorptionHours: Double = val maxAbsorptionHours: Double =
if (isAAPSOrWeighted) sp.getDouble(info.nightscout.core.utils.R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME) if (isAAPSOrWeighted) sp.getDouble(info.nightscout.core.utils.R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
else sp.getDouble(info.nightscout.core.utils.R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME) else sp.getDouble(info.nightscout.core.utils.R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
@ -102,7 +106,7 @@ class AutosensDataObject(injector: HasAndroidInjector) : AutosensData {
} }
} }
fun deductAbsorbedCarbs() { override fun deductAbsorbedCarbs() {
var ac = absorbed var ac = absorbed
var i = 0 var i = 0
while (i < activeCarbsList.size && ac > 0) { while (i < activeCarbsList.size && ac > 0) {
@ -115,7 +119,4 @@ class AutosensDataObject(injector: HasAndroidInjector) : AutosensData {
i++ i++
} }
} }
init {
injector.androidInjector().inject(this)
}
} }

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/overview_buttons" android:id="@+id/buttons_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
@ -28,7 +28,6 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/buttons_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/graphs_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">

View file

@ -2,7 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/status_lights" android:id="@+id/status_lights_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"

View file

@ -198,7 +198,7 @@
</LinearLayout> </LinearLayout>
<info.nightscout.plugins.insulin.ActivityGraph <info.nightscout.core.graph.ActivityGraph
android:id="@+id/insulin_graph" android:id="@+id/insulin_graph"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="100dip" android:layout_height="100dip"

View file

@ -109,25 +109,6 @@
<string name="sms_wrong_tbr_duration">TBR duration must be a multiple of %1$d minutes and greater than 0.</string> <string name="sms_wrong_tbr_duration">TBR duration must be a multiple of %1$d minutes and greater than 0.</string>
<string name="a11y_otp_qr_code">QR Code for setup one time password</string> <string name="a11y_otp_qr_code">QR Code for setup one time password</string>
<!-- Insulin -->
<string name="key_insulin_oref_peak" translatable="false">insulin_oref_peak</string>
<string name="key_insulin_oref_peak_settings" translatable="false">insulin_oref_peak_settings</string>
<string name="lyumjev">Lyumjev</string>
<string name="description_insulin_rapid">Insulin preset for Humalog and NovoRapid / NovoLog</string>
<string name="description_insulin_ultra_rapid">Insulin preset for Fiasp</string>
<string name="description_insulin_lyumjev">Insulin preset for Lyumjev</string>
<string name="description_insulin_free_peak">Allows you to define the peak of the insulin activity and should only be used by advanced users</string>
<string name="insulin_shortname">INS</string>
<string name="insulin_oref_peak">IOB Curve Peak Time</string>
<string name="insulin_peak_time">Peak Time [min]</string>
<string name="free_peak_oref">Free-Peak Oref</string>
<string name="rapid_acting_oref">Rapid-Acting Oref</string>
<string name="ultra_rapid_oref">Ultra-Rapid Oref</string>
<string name="dia_too_short">DIA of %1$f too short - using %2$f instead!</string>
<string name="fast_acting_insulin_comment">Novorapid, Novolog, Humalog</string>
<string name="ultra_fast_acting_insulin_comment">Fiasp</string>
<!-- xDrip status line --> <!-- xDrip status line -->
<string name="key_xdrip_status_detailed_iob" translatable="false">xdripstatus_detailediob</string> <string name="key_xdrip_status_detailed_iob" translatable="false">xdripstatus_detailediob</string>
<string name="key_xdrip_status_show_bgi" translatable="false">xdripstatus_showbgi</string> <string name="key_xdrip_status_show_bgi" translatable="false">xdripstatus_showbgi</string>

View file

@ -1,8 +1,10 @@
package info.nightscout.plugins.sync.nsclient.data package info.nightscout.plugins.sync.nsclient.data
import android.text.Spanned import android.text.Spanned
import dagger.Lazy
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.core.aps.APSResultObject import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.nsclient.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.utils.HtmlHelper import info.nightscout.interfaces.utils.HtmlHelper
@ -21,7 +23,8 @@ import javax.inject.Singleton
class ProcessedDeviceStatusDataImpl @Inject constructor( class ProcessedDeviceStatusDataImpl @Inject constructor(
private val rh: ResourceHelper, private val rh: ResourceHelper,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val sp: SP private val sp: SP,
private val loop: Lazy<Loop>
) : ProcessedDeviceStatusData { ) : ProcessedDeviceStatusData {
override var pumpData: ProcessedDeviceStatusData.PumpData? = null override var pumpData: ProcessedDeviceStatusData.PumpData? = null
@ -112,11 +115,10 @@ class ProcessedDeviceStatusDataImpl @Inject constructor(
override val openApsTimestamp: Long override val openApsTimestamp: Long
get() = if (openAPSData.clockSuggested != 0L) openAPSData.clockSuggested else -1 get() = if (openAPSData.clockSuggested != 0L) openAPSData.clockSuggested else -1
override fun getAPSResult(injector: HasAndroidInjector): APSResultObject { override fun getAPSResult(injector: HasAndroidInjector): APSResult =
val result = APSResultObject(injector) loop.get().provideEmptyAPSResultObject().also {
result.json = openAPSData.suggested it.json = openAPSData.suggested
result.date = openAPSData.clockSuggested it.date = openAPSData.clockSuggested
return result
} }
override val uploaderStatus: String override val uploaderStatus: String
get() { get() {

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="info.nightscout.comboctl.android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

View file

@ -18,6 +18,7 @@ include ':implementation'
include ':plugins:aps' include ':plugins:aps'
include ':plugins:automation' include ':plugins:automation'
include ':plugins:configuration' include ':plugins:configuration'
include ':plugins:insulin'
include ':plugins:main' include ':plugins:main'
include ':plugins:openhumans' include ':plugins:openhumans'
include ':plugins:sensitivity' include ':plugins:sensitivity'

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