diff --git a/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt b/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt index f20eed392a..e873bf5edf 100644 --- a/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt +++ b/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt @@ -1,7 +1,42 @@ package info.nightscout.androidaps +import android.os.SystemClock +import android.view.View +import android.view.ViewGroup +import androidx.test.espresso.Espresso.onData +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.action.ViewActions.scrollTo +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withClassName +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withTagValue +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest +import androidx.test.rule.ActivityTestRule +import androidx.test.rule.GrantPermissionRule +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin +import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin +import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin +import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin +import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin +import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin +import info.nightscout.androidaps.plugins.source.RandomBgPlugin +import info.nightscout.androidaps.setupwizard.SetupWizardActivity +import info.nightscout.androidaps.utils.HardLimits +import info.nightscout.androidaps.utils.extensions.isRunningTest +import org.hamcrest.CoreMatchers.allOf +import org.hamcrest.Description +import org.hamcrest.Matcher +import org.hamcrest.Matchers +import org.hamcrest.TypeSafeMatcher +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test import org.junit.runner.RunWith @LargeTest diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt index 00fe3c688f..d47573ef2f 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt @@ -8,18 +8,14 @@ import android.widget.ArrayAdapter import com.google.common.base.Joiner import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R -import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.databinding.DialogProfileswitchBinding import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.bus.RxBusWrapper -import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.resources.ResourceHelper @@ -35,9 +31,6 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var repository: AppRepository @Inject lateinit var uel: UserEntryLogger - @Inject lateinit var config: Config - @Inject lateinit var hardLimits: HardLimits - @Inject lateinit var rxBus: RxBusWrapper private var profileIndex: Int? = null @@ -136,33 +129,22 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime)) activity?.let { activity -> - val ps = profileFunction.buildProfileSwitch(profileStore, profileName, duration, percent, timeShift, eventTime) - val validity = ProfileSealed.PS(ps).isValid(resourceHelper.gs(R.string.careportal_profileswitch), activePlugin.activePump, config, resourceHelper, rxBus, hardLimits) - if (validity.isValid) - OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), { - profileFunction.createProfileSwitch(profileStore, - profileName = profileName, - durationInMinutes = duration, - percentage = percent, - timeShiftInHours = timeShift, - timestamp = eventTime) - uel.log(Action.PROFILE_SWITCH, - Sources.ProfileSwitchDialog, - notes, - ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, - ValueWithUnit.SimpleString(profileName), - ValueWithUnit.Percent(percent), - ValueWithUnit.Hour(timeShift).takeIf { timeShift != 0 }, - ValueWithUnit.Minute(duration).takeIf { duration != 0 }) - }) - else { - OKDialog.show( - activity, - resourceHelper.gs(R.string.careportal_profileswitch), - HtmlHelper.fromHtml(Joiner.on("
").join(validity.reasons)) - ) - return false - } + OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), { + profileFunction.createProfileSwitch(profileStore, + profileName = profileName, + durationInMinutes = duration, + percentage = percent, + timeShiftInHours = timeShift, + timestamp = eventTime) + uel.log(Action.PROFILE_SWITCH, + Sources.ProfileSwitchDialog, + notes, + ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, + ValueWithUnit.SimpleString(profileName), + ValueWithUnit.Percent(percent), + ValueWithUnit.Hour(timeShift).takeIf { timeShift != 0 }, + ValueWithUnit.Minute(duration).takeIf { duration != 0 }) + }) } return true } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt index 5ee8e69839..c6955fcd34 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt @@ -46,6 +46,7 @@ import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAc import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt index 479acd4da0..f697f23e20 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt @@ -125,11 +125,11 @@ class OpenAPSAMAPlugin @Inject constructor( maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble()) targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble()) } - if (!hardLimits.checkHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return - if (!hardLimits.checkHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return - if (!hardLimits.checkHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return - if (!hardLimits.checkHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return - if (!hardLimits.checkHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return + if (!hardLimits.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return + if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return + if (!hardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return + if (!hardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return + if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return startPart = System.currentTimeMillis() if (constraintChecker.isAutosensModeEnabled().value()) { val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin") diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt index e658f2d04c..3b65f213f7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt @@ -130,11 +130,11 @@ class OpenAPSSMBPlugin @Inject constructor( maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble()) targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble()) } - if (!hardLimits.checkHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return - if (!hardLimits.checkHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return - if (!hardLimits.checkHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return - if (!hardLimits.checkHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return - if (!hardLimits.checkHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return + if (!hardLimits.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return + if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return + if (!hardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return + if (!hardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return + if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return startPart = System.currentTimeMillis() if (constraintChecker.isAutosensModeEnabled().value()) { val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin") diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt index 5cf7bb4371..3de63dbbd5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt @@ -91,10 +91,10 @@ class ProfileFunctionImplementation @Inject constructor( if (sp.getString(R.string.key_units, Constants.MGDL) == Constants.MGDL) GlucoseUnit.MGDL else GlucoseUnit.MMOL - override fun buildProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long) : ProfileSwitch { + override fun createProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long) { val pureProfile = profileStore.getSpecificProfile(profileName) ?: throw InvalidParameterSpecException(profileName) - return ProfileSwitch( + val ps = ProfileSwitch( timestamp = timestamp, basalBlocks = pureProfile.basalBlocks, isfBlocks = pureProfile.isfBlocks, @@ -105,14 +105,8 @@ class ProfileFunctionImplementation @Inject constructor( timeshift = T.hours(timeShiftInHours.toLong()).msecs(), percentage = percentage, duration = T.mins(durationInMinutes.toLong()).msecs(), - insulinConfiguration = activePlugin.activeInsulin.insulinConfiguration.also { - it.insulinEndTime = (pureProfile.dia * 3600 * 1000).toLong() - } + insulinConfiguration = activePlugin.activeInsulin.insulinConfiguration.also { it.insulinEndTime = (pureProfile.dia * 3600 * 1000).toLong() } ) - } - - override fun createProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long) { - val ps = buildProfileSwitch(profileStore, profileName, durationInMinutes, percentage, timeShiftInHours, timestamp) disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps)) .subscribe({ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index bddee95f50..cfc0eaac7e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -740,7 +740,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList graphData.addTreatments() if (menuChartSettings[0][OverviewMenus.CharType.ACT.ordinal]) graphData.addActivity(0.8) - if ((pump.pumpDescription.isTempBasalCapable || config.NSCLIENT) && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal]) + if (pump.pumpDescription.isTempBasalCapable && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal]) graphData.addBasals() graphData.addTargetLine() graphData.addNowLine(dateUtil.now()) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt index 8d640afc75..b65a284149 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt @@ -28,7 +28,6 @@ import info.nightscout.androidaps.setupwizard.elements.* import info.nightscout.androidaps.setupwizard.events.EventSWUpdate import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.CryptoUtil -import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.extensions.isRunningTest import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP @@ -54,8 +53,7 @@ class SWDefinition @Inject constructor( private val importExportPrefs: ImportExportPrefs, private val androidPermission: AndroidPermission, private val cryptoUtil: CryptoUtil, - private val config: Config, - private val hardLimits: HardLimits + private val config: Config ) { lateinit var activity: AppCompatActivity @@ -257,7 +255,7 @@ class SWDefinition @Inject constructor( .add(SWFragment(injector, this) .add(LocalProfileFragment())) .validator { - localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus, hardLimits).isValid } + localProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) } ?: false } .visibility { localProfilePlugin.isEnabled() } diff --git a/core/src/main/java/info/nightscout/androidaps/utils/HardLimits.kt b/app/src/main/java/info/nightscout/androidaps/utils/HardLimits.kt similarity index 92% rename from core/src/main/java/info/nightscout/androidaps/utils/HardLimits.kt rename to app/src/main/java/info/nightscout/androidaps/utils/HardLimits.kt index 67118d0908..0389b34283 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/HardLimits.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/HardLimits.kt @@ -1,8 +1,7 @@ package info.nightscout.androidaps.utils import android.content.Context -import info.nightscout.androidaps.annotations.OpenForTesting -import info.nightscout.androidaps.core.R +import info.nightscout.androidaps.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction import info.nightscout.androidaps.logging.AAPSLogger @@ -16,7 +15,6 @@ import javax.inject.Singleton import kotlin.math.max import kotlin.math.min -@OpenForTesting @Singleton class HardLimits @Inject constructor( private val aapsLogger: AAPSLogger, @@ -83,12 +81,9 @@ class HardLimits @Inject constructor( fun maxIC(): Double = MAX_IC[loadAge()] // safety checks - fun checkHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean = + fun checkOnlyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean = value == verifyHardLimits(value, valueName, lowLimit, highLimit) - fun isInRange(value: Double, lowLimit: Double, highLimit: Double): Boolean = - value in lowLimit..highLimit - fun verifyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Double { var newValue = value if (newValue < lowLimit || newValue > highLimit) { @@ -103,4 +98,4 @@ class HardLimits @Inject constructor( } return newValue } -} \ No newline at end of file +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a248a82b14..8e2e35aecf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -250,6 +250,8 @@ Loop has been disabled Loop has been enabled Loop is enabled + %1$.2f limited to %2$.2f + »%1$s« is out of hard limits To connect pump reply with code %1$s Connection to pump failed To disconnect pump for %1$d minutes reply with code %2$s @@ -398,6 +400,12 @@ Adult Insulin resistant adult Pregnancy + age + child + teenage + adult + resistantadult + pregnant Please select patient type to setup safety limits Patient name Please provide patient name or nickname to differentiate among multiple setups @@ -1074,6 +1082,16 @@ Email address Privacy setting You can provide optional email address if you want to be notified about app crashes. This is not an automated service. You will be contacted by developers in dangerous situations. + Profile low target + Profile high target + Temporary target bottom value + Temporary target top value + Temporary target value + Profile DIA value + Profile sensitivity value + Maximal profile basal value + Current basal value + Profile carbs ratio value Full sync Prime Synchronization diff --git a/core/src/main/java/info/nightscout/androidaps/data/ProfileSealed.kt b/core/src/main/java/info/nightscout/androidaps/data/ProfileSealed.kt index f47f1a534f..50b39e896b 100644 --- a/core/src/main/java/info/nightscout/androidaps/data/ProfileSealed.kt +++ b/core/src/main/java/info/nightscout/androidaps/data/ProfileSealed.kt @@ -19,8 +19,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.HardLimits -import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.resources.ResourceHelper import org.json.JSONArray @@ -96,93 +94,34 @@ sealed class ProfileSealed( value.timeZone.rawOffset.toLong() ) - override fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper, hardLimits: HardLimits): Profile.ValidityCheck { + override fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper): Boolean { val notify = true - val validityCheck = Profile.ValidityCheck() + var valid = true val description = pump.pumpDescription - for (basal in basalBlocks) { - val basalAmount = basal.amount * percentage / 100.0 - if (!description.is30minBasalRatesCapable) { + if (!description.is30minBasalRatesCapable) { + for (basal in basalBlocks) { // Check for hours alignment val duration: Long = basal.duration if (duration % 3600000 != 0L) { if (notify && config.APS) { - val notification = Notification( - Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, - resourceHelper.gs(R.string.basalprofilenotaligned, from), - Notification.NORMAL - ) + val notification = Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, resourceHelper.gs(R.string.basalprofilenotaligned, from), Notification.NORMAL) rxBus.send(EventNewNotification(notification)) } - validityCheck.isValid = false - validityCheck.reasons.add( - resourceHelper.gs( - R.string.basalprofilenotaligned, - from - ) - ) - break + valid = false + } + // Check for minimal basal value + if (basal.amount < description.basalMinimumRate) { + basal.amount = description.basalMinimumRate + if (notify) sendBelowMinimumNotification(from, rxBus, resourceHelper) + valid = false + } else if (basal.amount > description.basalMaximumRate) { + basal.amount = description.basalMaximumRate + if (notify) sendAboveMaximumNotification(from, rxBus, resourceHelper) + valid = false } } - // Check for minimal basal value - if (basalAmount < description.basalMinimumRate) { - basal.amount = description.basalMinimumRate - if (notify) sendBelowMinimumNotification(from, rxBus, resourceHelper) - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.minimalbasalvaluereplaced, from)) - break - } else if (basalAmount > description.basalMaximumRate) { - basal.amount = description.basalMaximumRate - if (notify) sendAboveMaximumNotification(from, rxBus, resourceHelper) - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.maximumbasalvaluereplaced, from)) - break - } - if (!hardLimits.isInRange(basalAmount, 0.01, hardLimits.maxBasal())) { - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.basal_value), basalAmount)) - break - } } - if (!hardLimits.isInRange(dia, hardLimits.minDia(), hardLimits.maxDia())) { - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_dia), dia)) - } - for (ic in icBlocks) - if (!hardLimits.isInRange(ic.amount * 100.0 / percentage, hardLimits.minIC(), hardLimits.maxIC())) { - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_carbs_ratio_value), ic.amount * 100.0 / percentage)) - break - } - for (isf in isfBlocks) - if (!hardLimits.isInRange(toMgdl(isf.amount * 100.0 / percentage, units), HardLimits.MIN_ISF, HardLimits.MAX_ISF)) { - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_sensitivity_value), isf.amount * 100.0 / percentage)) - break - } - for (target in targetBlocks) { - if (hardLimits.isInRange( - Round.roundTo(target.lowTarget, 0.1), - HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), - HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble() - ) - ) { - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_low_target), target.lowTarget)) - break - } - if (hardLimits.isInRange( - Round.roundTo(target.highTarget, 0.1), - HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), - HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble() - ) - ) { - validityCheck.isValid = false - validityCheck.reasons.add(resourceHelper.gs(R.string.value_out_of_hard_limits, resourceHelper.gs(R.string.profile_high_target), target.highTarget)) - break - } - } - return validityCheck + return valid } protected open fun sendBelowMinimumNotification(from: String, rxBus: RxBusWrapper, resourceHelper: ResourceHelper) { diff --git a/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt b/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt index ccb87c0704..1f4c88e3ab 100644 --- a/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt +++ b/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt @@ -17,18 +17,15 @@ import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.extensions.getCustomizedName import info.nightscout.androidaps.extensions.pureProfileFromJson -import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.resources.ResourceHelper import org.json.JSONObject -import java.io.File.separator import java.text.DecimalFormat import javax.inject.Inject @@ -42,7 +39,6 @@ class ProfileViewerDialog : DaggerDialogFragment() { @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var config: Config @Inject lateinit var rxBus: RxBusWrapper - @Inject lateinit var hardLimits: HardLimits private var time: Long = 0 @@ -153,9 +149,7 @@ class ProfileViewerDialog : DaggerDialogFragment() { } binding.noprofile.visibility = View.GONE - val validity = profile1.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus, hardLimits) - binding.invalidprofile.text = resourceHelper.gs(R.string.invalidprofile) + "\n" + validity.reasons.joinToString(separator = "\n") - binding.invalidprofile.visibility = validity.isValid.not().toVisibility() + binding.invalidprofile.visibility = if (profile1.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus)) View.GONE else View.VISIBLE } else profile?.let { @@ -170,9 +164,7 @@ class ProfileViewerDialog : DaggerDialogFragment() { binding.basalGraph.show(it) binding.noprofile.visibility = View.GONE - val validity = it.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus, hardLimits) - binding.invalidprofile.text = resourceHelper.gs(R.string.invalidprofile) + "\n" + validity.reasons.joinToString(separator = "\n") - binding.invalidprofile.visibility = validity.isValid.not().toVisibility() + binding.invalidprofile.visibility = if (it.isValid("ProfileViewDialog", activePlugin.activePump, config, resourceHelper, rxBus)) View.GONE else View.VISIBLE } } diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt index 2cd9ac88f5..3d43cdc60f 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt @@ -6,7 +6,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to1Decimal -import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.resources.ResourceHelper import org.joda.time.DateTime @@ -14,9 +13,7 @@ import org.json.JSONObject interface Profile { - class ValidityCheck(var isValid: Boolean = true, val reasons: ArrayList = arrayListOf()) - - fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper, hardLimits: HardLimits): ValidityCheck + fun isValid(from: String, pump: Pump, config: Config, resourceHelper: ResourceHelper, rxBus: RxBusWrapper): Boolean /** * Units used for ISF & target diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileFunction.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileFunction.kt index 3cc7939446..0b4829dad3 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileFunction.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileFunction.kt @@ -46,18 +46,6 @@ interface ProfileFunction { */ fun getRequestedProfile(): ProfileSwitch? - /** - * Build a new circadian profile switch request based on provided profile - * - * @param profileStore ProfileStore to use - * @param profileName this profile from profile store - * @param durationInMinutes - * @param percentage 100 = no modification - * @param timeShiftInHours 0 = no modification - * @param timestamp expected time - */ - fun buildProfileSwitch(profileStore: ProfileStore, profileName: String, durationInMinutes: Int, percentage: Int, timeShiftInHours: Int, timestamp: Long): ProfileSwitch - /** * Create a new circadian profile switch request based on provided profile * diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt index 003d8f569e..136e899a2c 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt @@ -63,7 +63,7 @@ class PumpDescription() { is30minBasalRatesCapable = false isRefillingCapable = true isBatteryReplaceable = true - storesCarbInfo = false + storesCarbInfo = true supportsTDDs = false needsManualTDDLoad = true hasCustomUnreachableAlertCheck = false diff --git a/core/src/main/java/info/nightscout/androidaps/utils/sharedPreferences/SPImplementation.kt b/core/src/main/java/info/nightscout/androidaps/utils/sharedPreferences/SPImplementation.kt index 52f5c61f26..5231a2e4ad 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/sharedPreferences/SPImplementation.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/sharedPreferences/SPImplementation.kt @@ -90,11 +90,7 @@ class SPImplementation @Inject constructor( return try { sharedPreferences.getLong(key, defaultValue) } catch (e: Exception) { - try { - SafeParse.stringToLong(sharedPreferences.getString(key, defaultValue.toString())) - } catch (e: Exception) { - defaultValue - } + SafeParse.stringToLong(sharedPreferences.getString(key, defaultValue.toString())) } } diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 2b813deedc..838e4d7acf 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -57,12 +57,6 @@ active_pump_change_timestamp active_pump_type active_pump_serial_number - age - child - teenage - adult - resistantadult - pregnant Refresh @@ -478,22 +472,6 @@ LOOP REMOVED OTHER - - Profile low target - Profile high target - Temporary target bottom value - Temporary target top value - Temporary target value - Profile DIA value - Profile sensitivity value - Maximal profile basal value - Current basal value - Profile carbs ratio value - %1$.2f limited to %2$.2f - »%1$s« is out of hard limits - »%1$s« %2$.2f is out of hard limits - Basal value - %1$d day %1$d days diff --git a/core/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt b/core/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt index 3c1e6b5732..d141926a7e 100644 --- a/core/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt @@ -2,10 +2,11 @@ package info.nightscout.androidaps.data import android.content.Context import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.core.R -import info.nightscout.androidaps.database.AppRepository +import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.extensions.pureProfileFromJson import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Config @@ -13,18 +14,18 @@ import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.rx.TestAapsSchedulers -import info.nightscout.androidaps.utils.sharedPreferences.SP import org.json.JSONObject import org.junit.Assert import org.junit.Before import org.junit.Test import org.mockito.Mock import org.mockito.Mockito.`when` +import org.mockito.Mockito.any import org.mockito.Mockito.anyInt import org.mockito.Mockito.anyString +import org.mockito.Mockito.doNothing import java.util.* /** @@ -37,29 +38,25 @@ class ProfileTest : TestBase() { @Mock lateinit var resourceHelper: ResourceHelper @Mock lateinit var context: Context @Mock lateinit var config: Config - @Mock lateinit var sp: SP - @Mock lateinit var repository: AppRepository private lateinit var rxBus: RxBusWrapper private lateinit var dateUtil: DateUtil private lateinit var testPumpPlugin: TestPumpPlugin - private lateinit var hardLimits: HardLimits - private var okProfile = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"sens\":[{\"time\":\"00:00\",\"value\":\"6\"},{\"time\":\"2:00\",\"value\":\"6.2\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - private var belowLimitValidProfile = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.001\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - private var notAlignedBasalValidProfile = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:30\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - private var notStartingAtZeroValidProfile = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:30\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - private var noUnitsValidProfile = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\"}" - private var wrongProfile = "{\"dia\":\"5\",\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var okProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var belowLimitValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.001\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var notAlignedBasalValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:30\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var notStartingAtZeroValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:30\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var noUnitsValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\"}" + private var wrongProfile = "{\"dia\":\"3\",\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" //String profileStore = "{\"defaultProfile\":\"Default\",\"store\":{\"Default\":" + validProfile + "}}"; @Before fun prepare() { - testPumpPlugin = TestPumpPlugin { AndroidInjector { } } + testPumpPlugin = TestPumpPlugin(HasAndroidInjector { AndroidInjector { } }) dateUtil = DateUtil(context) rxBus = RxBusWrapper(TestAapsSchedulers()) - hardLimits = HardLimits(aapsLogger, rxBus, sp, resourceHelper, context, repository) `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin) `when`(resourceHelper.gs(R.string.profile_per_unit)).thenReturn("/U") `when`(resourceHelper.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U") @@ -72,10 +69,10 @@ class ProfileTest : TestBase() { // Test valid profile var p = ProfileSealed.Pure(pureProfileFromJson(JSONObject(okProfile), dateUtil)!!) - Assert.assertEquals(true, p.isValid("Test", testPumpPlugin, config, resourceHelper, rxBus, hardLimits).isValid) + Assert.assertEquals(true, p.isValid("Test", testPumpPlugin, config, resourceHelper, rxBus)) // Assert.assertEquals(true, p.log().contains("NS units: mmol")) // JSONAssert.assertEquals(JSONObject(okProfile), p.toPureNsJson(dateUtil), false) - Assert.assertEquals(5.0, p.dia, 0.01) + Assert.assertEquals(3.0, p.dia, 0.01) // Assert.assertEquals(TimeZone.getTimeZone("UTC"), p.timeZone) Assert.assertEquals("00:30", dateUtil.format_HH_MM(30 * 60)) val c = Calendar.getInstance() @@ -83,13 +80,13 @@ class ProfileTest : TestBase() { c[Calendar.MINUTE] = 0 c[Calendar.SECOND] = 0 c[Calendar.MILLISECOND] = 0 - Assert.assertEquals(108.0, p.getIsfMgdl(c.timeInMillis), 0.01) + Assert.assertEquals(1800.0, p.getIsfMgdl(c.timeInMillis), 0.01) c[Calendar.HOUR_OF_DAY] = 2 - Assert.assertEquals(111.6, p.getIsfMgdl(c.timeInMillis), 0.01) + Assert.assertEquals(1980.0, p.getIsfMgdl(c.timeInMillis), 0.01) // Assert.assertEquals(110.0, p.getIsfTimeFromMidnight(2 * 60 * 60), 0.01) Assert.assertEquals(""" - 00:00 6,0 mmol/U - 02:00 6,2 mmol/U + 00:00 100,0 mmol/U + 02:00 110,0 mmol/U """.trimIndent(), p.getIsfList(resourceHelper, dateUtil).replace(".", ",")) Assert.assertEquals(30.0, p.getIc(c.timeInMillis), 0.01) Assert.assertEquals(30.0, p.getIcTimeFromMidnight(2 * 60 * 60), 0.01) @@ -124,7 +121,7 @@ class ProfileTest : TestBase() { //Test basal profile below limit p = ProfileSealed.Pure(pureProfileFromJson(JSONObject(belowLimitValidProfile), dateUtil)!!) - p.isValid("Test", testPumpPlugin, config, resourceHelper, rxBus, hardLimits) + p.isValid("Test", testPumpPlugin, config, resourceHelper, rxBus) // Test profile w/o units Assert.assertNull(pureProfileFromJson(JSONObject(noUnitsValidProfile), dateUtil)) @@ -142,21 +139,21 @@ class ProfileTest : TestBase() { Assert.assertEquals(0.05, p.getBasal(c.timeInMillis), 0.01) Assert.assertEquals(1.2, p.percentageBasalSum(), 0.01) Assert.assertEquals(60.0, p.getIc(c.timeInMillis), 0.01) - Assert.assertEquals(223.2, p.getIsfMgdl(c.timeInMillis), 0.01) + Assert.assertEquals(3960.0, p.getIsfMgdl(c.timeInMillis), 0.01) // Test timeshift functionality p = ProfileSealed.Pure(pureProfileFromJson(JSONObject(okProfile), dateUtil)!!) p.ts = 1 Assert.assertEquals( """ - 00:00 6.2 mmol/U - 01:00 6.0 mmol/U - 03:00 6.2 mmol/U + 00:00 110.0 mmol/U + 01:00 100.0 mmol/U + 03:00 110.0 mmol/U """.trimIndent(), p.getIsfList(resourceHelper, dateUtil)) // Test hour alignment testPumpPlugin.pumpDescription.is30minBasalRatesCapable = false p = ProfileSealed.Pure(pureProfileFromJson(JSONObject(notAlignedBasalValidProfile), dateUtil)!!) - p.isValid("Test", testPumpPlugin, config, resourceHelper, rxBus, hardLimits) + p.isValid("Test", testPumpPlugin, config, resourceHelper, rxBus) } } \ No newline at end of file