Merge branch 'User_Entry_ValueWithUnits' into UE_ExportXML

This commit is contained in:
Philoul 2021-03-08 18:22:50 +01:00
commit f7f6f4b7c1
149 changed files with 2127 additions and 2464 deletions

View file

@ -2,6 +2,22 @@
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<option name="AUTODETECT_INDENTS" value="false" /> <option name="AUTODETECT_INDENTS" value="false" />
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" /> <option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" /> <option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" /> <option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />

View file

@ -13,6 +13,7 @@ jacoco {
tasks.withType(Test) { tasks.withType(Test) {
jacoco.includeNoLocationClasses = true jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
} }
repositories { repositories {

View file

@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.toVisibility import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -314,7 +315,7 @@ class WizardDialog : DaggerDialogFragment() {
bg = if (binding.bgcheckbox.isChecked) bg else 0.0 bg = if (binding.bgcheckbox.isChecked) bg else 0.0
val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet() val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet()
val tempTarget = if (binding.ttcheckbox.isChecked && dbRecord is ValueWrapper.Existing) dbRecord.value else null val tempTarget = if (binding.ttcheckbox.isChecked && dbRecord is ValueWrapper.Existing) dbRecord.value else null
// COB // COB
var cob = 0.0 var cob = 0.0

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.CareportalEvent import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange import info.nightscout.androidaps.events.EventAcceptOpenLoopChange
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.events.EventNewBG import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.events.EventTempTargetChange import info.nightscout.androidaps.events.EventTempTargetChange
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
@ -33,10 +34,9 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
@ -76,8 +76,7 @@ open class LoopPlugin @Inject constructor(
private val receiverStatusStore: ReceiverStatusStore, private val receiverStatusStore: ReceiverStatusStore,
private val fabricPrivacy: FabricPrivacy, private val fabricPrivacy: FabricPrivacy,
private val nsUpload: NSUpload, private val nsUpload: NSUpload,
private val databaseHelper: DatabaseHelperInterface, private val databaseHelper: DatabaseHelperInterface
private val hardLimits: HardLimits
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.LOOP) .mainType(PluginType.LOOP)
.fragmentClass(LoopFragment::class.java.name) .fragmentClass(LoopFragment::class.java.name)
@ -198,7 +197,7 @@ open class LoopPlugin @Inject constructor(
val apsMode = sp.getString(R.string.key_aps_mode, "open") val apsMode = sp.getString(R.string.key_aps_mode, "open")
val pump = activePlugin.activePump val pump = activePlugin.activePump
var isLGS = false var isLGS = false
if (!isSuspended && !pump.isSuspended()) if (closedLoopEnabled.value()) if (maxIobAllowed == hardLimits.MAXIOB_LGS || apsMode == "lgs") isLGS = true if (!isSuspended && !pump.isSuspended()) if (closedLoopEnabled.value()) if (maxIobAllowed == HardLimits.MAX_IOB_LGS || apsMode == "lgs") isLGS = true
return isLGS return isLGS
} }
@ -509,18 +508,18 @@ open class LoopPlugin @Inject constructor(
*/ */
private fun applyTBRRequest(request: APSResult?, profile: Profile?, callback: Callback?) { private fun applyTBRRequest(request: APSResult?, profile: Profile?, callback: Callback?) {
if (!request!!.tempBasalRequested) { if (!request!!.tempBasalRequested) {
callback?.result(PumpEnactResult(injector).enacted(false).success(true).comment(resourceHelper.gs(R.string.nochangerequested)))?.run() callback?.result(PumpEnactResult(injector).enacted(false).success(true).comment(R.string.nochangerequested))?.run()
return return
} }
val pump = activePlugin.activePump val pump = activePlugin.activePump
if (!pump.isInitialized()) { if (!pump.isInitialized()) {
aapsLogger.debug(LTag.APS, "applyAPSRequest: " + resourceHelper.gs(R.string.pumpNotInitialized)) aapsLogger.debug(LTag.APS, "applyAPSRequest: " + resourceHelper.gs(R.string.pumpNotInitialized))
callback?.result(PumpEnactResult(injector).comment(resourceHelper.gs(R.string.pumpNotInitialized)).enacted(false).success(false))?.run() callback?.result(PumpEnactResult(injector).comment(R.string.pumpNotInitialized).enacted(false).success(false))?.run()
return return
} }
if (pump.isSuspended()) { if (pump.isSuspended()) {
aapsLogger.debug(LTag.APS, "applyAPSRequest: " + resourceHelper.gs(R.string.pumpsuspended)) aapsLogger.debug(LTag.APS, "applyAPSRequest: " + resourceHelper.gs(R.string.pumpsuspended))
callback?.result(PumpEnactResult(injector).comment(resourceHelper.gs(R.string.pumpsuspended)).enacted(false).success(false))?.run() callback?.result(PumpEnactResult(injector).comment(R.string.pumpsuspended).enacted(false).success(false))?.run()
return return
} }
aapsLogger.debug(LTag.APS, "applyAPSRequest: $request") aapsLogger.debug(LTag.APS, "applyAPSRequest: $request")
@ -534,13 +533,13 @@ open class LoopPlugin @Inject constructor(
} else { } else {
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly") aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
callback?.result(PumpEnactResult(injector).percent(request.percent).duration(0) callback?.result(PumpEnactResult(injector).percent(request.percent).duration(0)
.enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly)))?.run() .enacted(false).success(true).comment(R.string.basal_set_correctly))?.run()
} }
} else if (activeTemp != null && activeTemp.plannedRemainingMinutes > 5 && request.duration - activeTemp.plannedRemainingMinutes < 30 && request.percent == activeTemp.percentRate) { } else if (activeTemp != null && activeTemp.plannedRemainingMinutes > 5 && request.duration - activeTemp.plannedRemainingMinutes < 30 && request.percent == activeTemp.percentRate) {
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly") aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
callback?.result(PumpEnactResult(injector).percent(request.percent) callback?.result(PumpEnactResult(injector).percent(request.percent)
.enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes) .enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes)
.comment(resourceHelper.gs(R.string.let_temp_basal_run)))?.run() .comment(R.string.let_temp_basal_run))?.run()
} else { } else {
aapsLogger.debug(LTag.APS, "applyAPSRequest: tempBasalPercent()") aapsLogger.debug(LTag.APS, "applyAPSRequest: tempBasalPercent()")
commandQueue.tempBasalPercent(request.percent, request.duration, false, profile!!, callback) commandQueue.tempBasalPercent(request.percent, request.duration, false, profile!!, callback)
@ -553,13 +552,13 @@ open class LoopPlugin @Inject constructor(
} else { } else {
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly") aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
callback?.result(PumpEnactResult(injector).absolute(request.rate).duration(0) callback?.result(PumpEnactResult(injector).absolute(request.rate).duration(0)
.enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly)))?.run() .enacted(false).success(true).comment(R.string.basal_set_correctly))?.run()
} }
} else if (activeTemp != null && activeTemp.plannedRemainingMinutes > 5 && request.duration - activeTemp.plannedRemainingMinutes < 30 && abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.pumpDescription.basalStep) { } else if (activeTemp != null && activeTemp.plannedRemainingMinutes > 5 && request.duration - activeTemp.plannedRemainingMinutes < 30 && abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.pumpDescription.basalStep) {
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly") aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
callback?.result(PumpEnactResult(injector).absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile)) callback?.result(PumpEnactResult(injector).absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
.enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes) .enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes)
.comment(resourceHelper.gs(R.string.let_temp_basal_run)))?.run() .comment(R.string.let_temp_basal_run))?.run()
} else { } else {
aapsLogger.debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()") aapsLogger.debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()")
commandQueue.tempBasalAbsolute(request.rate, request.duration, false, profile!!, callback) commandQueue.tempBasalAbsolute(request.rate, request.duration, false, profile!!, callback)
@ -576,18 +575,18 @@ open class LoopPlugin @Inject constructor(
if (lastBolusTime != 0L && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { if (lastBolusTime != 0L && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval") aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
callback?.result(PumpEnactResult(injector) callback?.result(PumpEnactResult(injector)
.comment(resourceHelper.gs(R.string.smb_frequency_exceeded)) .comment(R.string.smb_frequency_exceeded)
.enacted(false).success(false))?.run() .enacted(false).success(false))?.run()
return return
} }
if (!pump.isInitialized()) { if (!pump.isInitialized()) {
aapsLogger.debug(LTag.APS, "applySMBRequest: " + resourceHelper.gs(R.string.pumpNotInitialized)) aapsLogger.debug(LTag.APS, "applySMBRequest: " + resourceHelper.gs(R.string.pumpNotInitialized))
callback?.result(PumpEnactResult(injector).comment(resourceHelper.gs(R.string.pumpNotInitialized)).enacted(false).success(false))?.run() callback?.result(PumpEnactResult(injector).comment(R.string.pumpNotInitialized).enacted(false).success(false))?.run()
return return
} }
if (pump.isSuspended()) { if (pump.isSuspended()) {
aapsLogger.debug(LTag.APS, "applySMBRequest: " + resourceHelper.gs(R.string.pumpsuspended)) aapsLogger.debug(LTag.APS, "applySMBRequest: " + resourceHelper.gs(R.string.pumpsuspended))
callback?.result(PumpEnactResult(injector).comment(resourceHelper.gs(R.string.pumpsuspended)).enacted(false).success(false))?.run() callback?.result(PumpEnactResult(injector).comment(R.string.pumpsuspended).enacted(false).success(false))?.run()
return return
} }
aapsLogger.debug(LTag.APS, "applySMBRequest: $request") aapsLogger.debug(LTag.APS, "applySMBRequest: $request")

View file

@ -113,20 +113,20 @@ open class OpenAPSAMAPlugin @Inject constructor(
val maxIob = constraintChecker.getMaxIOBAllowed().also { maxIOBAllowedConstraint -> val maxIob = constraintChecker.getMaxIOBAllowed().also { maxIOBAllowedConstraint ->
inputConstraints.copyReasons(maxIOBAllowedConstraint) inputConstraints.copyReasons(maxIOBAllowedConstraint)
}.value() }.value()
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, hardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble()) var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, hardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble()) var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble()) var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var isTempTarget = false var isTempTarget = false
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet() val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet()
if (tempTarget is ValueWrapper.Existing) { if (tempTarget is ValueWrapper.Existing) {
isTempTarget = true isTempTarget = true
minBg = hardLimits.verifyHardLimits(tempTarget.value.lowTarget, R.string.temp_target_low_target, hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1].toDouble()) minBg = hardLimits.verifyHardLimits(tempTarget.value.lowTarget, R.string.temp_target_low_target, HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1].toDouble())
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()) 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()) 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.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) 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.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, hardLimits.MINISF, hardLimits.MAXISF)) return if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, 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 if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis() startPart = System.currentTimeMillis()

View file

@ -119,20 +119,20 @@ open class OpenAPSSMBPlugin @Inject constructor(
inputConstraints.copyReasons(maxIOBAllowedConstraint) inputConstraints.copyReasons(maxIOBAllowedConstraint)
}.value() }.value()
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, hardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble()) var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, hardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble()) var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble()) var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var isTempTarget = false var isTempTarget = false
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet() val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet()
if (tempTarget is ValueWrapper.Existing) { if (tempTarget is ValueWrapper.Existing) {
isTempTarget = true isTempTarget = true
minBg = hardLimits.verifyHardLimits(tempTarget.value.lowTarget, R.string.temp_target_low_target, hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1].toDouble()) minBg = hardLimits.verifyHardLimits(tempTarget.value.lowTarget, R.string.temp_target_low_target, HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1].toDouble())
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()) 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()) 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.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) 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.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, hardLimits.MINISF, hardLimits.MAXISF)) return if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, 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 if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis() startPart = System.currentTimeMillis()

View file

@ -188,7 +188,7 @@ class SafetyPlugin @Inject constructor(
maxIob.setIfSmaller(aapsLogger, maxIobPref, String.format(resourceHelper.gs(R.string.limitingiob), maxIobPref, resourceHelper.gs(R.string.maxvalueinpreferences)), this) maxIob.setIfSmaller(aapsLogger, maxIobPref, String.format(resourceHelper.gs(R.string.limitingiob), maxIobPref, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
if (openAPSAMAPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobAMA(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobAMA(), resourceHelper.gs(R.string.hardlimit)), this) if (openAPSAMAPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobAMA(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobAMA(), resourceHelper.gs(R.string.hardlimit)), this)
if (openAPSSMBPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobSMB(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobSMB(), resourceHelper.gs(R.string.hardlimit)), this) if (openAPSSMBPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobSMB(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobSMB(), resourceHelper.gs(R.string.hardlimit)), this)
if (apsMode == "lgs") maxIob.setIfSmaller(aapsLogger, hardLimits.MAXIOB_LGS, String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.MAXIOB_LGS, resourceHelper.gs(R.string.lowglucosesuspend)), this) if (apsMode == "lgs") maxIob.setIfSmaller(aapsLogger, HardLimits.MAX_IOB_LGS, String.format(resourceHelper.gs(R.string.limitingiob), HardLimits.MAX_IOB_LGS, resourceHelper.gs(R.string.lowglucosesuspend)), this)
return maxIob return maxIob
} }
} }

View file

@ -40,10 +40,10 @@ open class StorageConstraintPlugin @Inject constructor(
aapsLogger.debug(LTag.CONSTRAINTS, "Internal storage free (Mb):$diskFree") aapsLogger.debug(LTag.CONSTRAINTS, "Internal storage free (Mb):$diskFree")
if (diskFree < Constants.MINIMUM_FREE_SPACE) { if (diskFree < Constants.MINIMUM_FREE_SPACE) {
value[aapsLogger, false, resourceHelper.gs(R.string.diskfull, Constants.MINIMUM_FREE_SPACE)] = this value[aapsLogger, false, resourceHelper.gs(R.string.diskfull, Constants.MINIMUM_FREE_SPACE)] = this
val notification = Notification(Notification.DISKFULL, resourceHelper.gs(R.string.diskfull, Constants.MINIMUM_FREE_SPACE), Notification.NORMAL) val notification = Notification(Notification.DISK_FULL, resourceHelper.gs(R.string.diskfull, Constants.MINIMUM_FREE_SPACE), Notification.NORMAL)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
} else { } else {
rxBus.send(EventDismissNotification(Notification.DISKFULL)) rxBus.send(EventDismissNotification(Notification.DISK_FULL))
} }
return value return value
} }

View file

@ -82,7 +82,7 @@ class VersionCheckerPlugin @Inject constructor(
gracePeriod.old, gracePeriod.old,
gracePeriod.veryOld gracePeriod.veryOld
) )
val notification = Notification(Notification.OLDVERSION, message, Notification.NORMAL) val notification = Notification(Notification.OLD_VERSION, message, Notification.NORMAL)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
} }
} }

View file

@ -491,7 +491,7 @@ public class NSClientPlugin extends PluginBase {
&& !enteredBy.equals(sp.getString("careportal_enteredby", "AndroidAPS"))) { && !enteredBy.equals(sp.getString("careportal_enteredby", "AndroidAPS"))) {
boolean defaultVal = config.getNSCLIENT(); boolean defaultVal = config.getNSCLIENT();
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) { if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60); Notification announcement = new Notification(Notification.NS_ANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
rxBus.send(new EventNewNotification(announcement)); rxBus.send(new EventNewNotification(announcement));
} }
} }

View file

@ -347,7 +347,7 @@ public class NSClientService extends DaggerService {
} }
rxBus.send(new EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " mins: " + reconnections.size() + "/" + WATCHDOG_MAXCONNECTIONS)); rxBus.send(new EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " mins: " + reconnections.size() + "/" + WATCHDOG_MAXCONNECTIONS));
if (reconnections.size() >= WATCHDOG_MAXCONNECTIONS) { if (reconnections.size() >= WATCHDOG_MAXCONNECTIONS) {
Notification n = new Notification(Notification.NSMALFUNCTION, resourceHelper.gs(R.string.nsmalfunction), Notification.URGENT); Notification n = new Notification(Notification.NS_MALFUNCTION, resourceHelper.gs(R.string.nsmalfunction), Notification.URGENT);
rxBus.send(new EventNewNotification(n)); rxBus.send(new EventNewNotification(n));
rxBus.send(new EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins")); rxBus.send(new EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins"));
nsClientPlugin.pause(true); nsClientPlugin.pause(true);
@ -508,8 +508,8 @@ public class NSClientService extends DaggerService {
try { try {
data = (JSONObject) args[0]; data = (JSONObject) args[0];
rxBus.send(new EventNSClientNewLog("CLEARALARM", "received")); rxBus.send(new EventNSClientNewLog("CLEARALARM", "received"));
rxBus.send(new EventDismissNotification(Notification.NSALARM)); rxBus.send(new EventDismissNotification(Notification.NS_ALARM));
rxBus.send(new EventDismissNotification(Notification.NSURGENTALARM)); rxBus.send(new EventDismissNotification(Notification.NS_URGENT_ALARM));
aapsLogger.debug(LTag.NSCLIENT, data.toString()); aapsLogger.debug(LTag.NSCLIENT, data.toString());
} catch (Exception e) { } catch (Exception e) {
aapsLogger.error("Unhandled exception", e); aapsLogger.error("Unhandled exception", e);
@ -710,8 +710,8 @@ public class NSClientService extends DaggerService {
} }
// Was that sgv more less 5 mins ago ? // Was that sgv more less 5 mins ago ?
if ((System.currentTimeMillis() - latestDateInReceivedData) / (60 * 1000L) < 5L) { if ((System.currentTimeMillis() - latestDateInReceivedData) / (60 * 1000L) < 5L) {
rxBus.send(new EventDismissNotification(Notification.NSALARM)); rxBus.send(new EventDismissNotification(Notification.NS_ALARM));
rxBus.send(new EventDismissNotification(Notification.NSURGENTALARM)); rxBus.send(new EventDismissNotification(Notification.NS_URGENT_ALARM));
} }
handleNewSgv(sgvs, isDelta); handleNewSgv(sgvs, isDelta);
} }

View file

@ -63,6 +63,8 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.directionToIcon import info.nightscout.androidaps.utils.extensions.directionToIcon
import info.nightscout.androidaps.utils.extensions.toVisibility import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -110,6 +112,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var overviewMenus: OverviewMenus @Inject lateinit var overviewMenus: OverviewMenus
@Inject lateinit var skinProvider: SkinProvider @Inject lateinit var skinProvider: SkinProvider
@Inject lateinit var trendCalculator: TrendCalculator
@Inject lateinit var config: Config @Inject lateinit var config: Config
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var databaseHelper: DatabaseHelperInterface @Inject lateinit var databaseHelper: DatabaseHelperInterface
@ -585,7 +588,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.bg.text = lastBG.valueToUnitsString(units) binding.infoLayout.bg.text = lastBG.valueToUnitsString(units)
binding.infoLayout.bg.setTextColor(color) binding.infoLayout.bg.setTextColor(color)
binding.infoLayout.arrow.setImageResource(lastBG.trendArrow.directionToIcon()) binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(lastBG).directionToIcon())
binding.infoLayout.arrow.setColorFilter(color) binding.infoLayout.arrow.setColorFilter(color)
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData val glucoseStatus = GlucoseStatus(injector).glucoseStatusData

View file

@ -68,7 +68,7 @@ class NotificationStore @Inject constructor(
store.add(n) store.add(n)
if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction) if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction)
raiseSystemNotification(n) raiseSystemNotification(n)
if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId) if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId!!)
Collections.sort(store, NotificationComparator()) Collections.sort(store, NotificationComparator())
return true return true
} }
@ -163,10 +163,10 @@ class NotificationStore @Inject constructor(
@Suppress("SetTextI18n") @Suppress("SetTextI18n")
holder.binding.text.text = dateUtil.timeString(notification.date) + " " + notification.text holder.binding.text.text = dateUtil.timeString(notification.date) + " " + notification.text
when (notification.level) { when (notification.level) {
Notification.URGENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent)) Notification.URGENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent))
Notification.NORMAL -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal)) Notification.NORMAL -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal))
Notification.LOW -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow)) Notification.LOW -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow))
Notification.INFO -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo)) Notification.INFO -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo))
Notification.ANNOUNCEMENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement)) Notification.ANNOUNCEMENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement))
} }
} }

View file

@ -38,21 +38,21 @@ class NotificationWithAction constructor(
date = System.currentTimeMillis() date = System.currentTimeMillis()
when (nsAlarm.level()) { when (nsAlarm.level()) {
0 -> { 0 -> {
id = NSANNOUNCEMENT id = NS_ANNOUNCEMENT
level = ANNOUNCEMENT level = ANNOUNCEMENT
text = nsAlarm.message() text = nsAlarm.message()
validTo = System.currentTimeMillis() + T.mins(60).msecs() validTo = System.currentTimeMillis() + T.mins(60).msecs()
} }
1 -> { 1 -> {
id = NSALARM id = NS_ALARM
level = NORMAL level = NORMAL
text = nsAlarm.title() text = nsAlarm.title()
soundId = R.raw.alarm soundId = R.raw.alarm
} }
2 -> { 2 -> {
id = NSURGENTALARM id = NS_URGENT_ALARM
level = URGENT level = URGENT
text = nsAlarm.title() text = nsAlarm.title()
soundId = R.raw.urgentalarm soundId = R.raw.urgentalarm

View file

@ -22,7 +22,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.IconsProvider import info.nightscout.androidaps.utils.resources.IconsProvider
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.valueToUnitsString import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton

View file

@ -42,6 +42,7 @@ import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.receivers.BundleStore import info.nightscout.androidaps.receivers.BundleStore
import info.nightscout.androidaps.receivers.DataReceiver import info.nightscout.androidaps.receivers.DataReceiver
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP

View file

@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -52,6 +53,7 @@ import javax.inject.Singleton
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.min import kotlin.math.min
@Suppress("SpellCheckingInspection")
@Singleton @Singleton
class ActionStringHandler @Inject constructor( class ActionStringHandler @Inject constructor(
private val sp: SP, private val sp: SP,
@ -75,7 +77,6 @@ class ActionStringHandler @Inject constructor(
private val danaRv2Plugin: DanaRv2Plugin, private val danaRv2Plugin: DanaRv2Plugin,
private val danaRSPlugin: DanaRSPlugin, private val danaRSPlugin: DanaRSPlugin,
private val danaPump: DanaPump, private val danaPump: DanaPump,
private val hardLimits: HardLimits,
private val carbsGenerator: CarbsGenerator, private val carbsGenerator: CarbsGenerator,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val config: Config, private val config: Config,
@ -84,7 +85,7 @@ class ActionStringHandler @Inject constructor(
private val nsUpload: NSUpload private val nsUpload: NSUpload
) { ) {
private val TIMEOUT = 65 * 1000 private val timeout = 65 * 1000
private var lastSentTimestamp: Long = 0 private var lastSentTimestamp: Long = 0
private var lastConfirmActionString: String? = null private var lastConfirmActionString: String? = null
private var lastBolusWizard: BolusWizard? = null private var lastBolusWizard: BolusWizard? = null
@ -113,14 +114,11 @@ class ActionStringHandler @Inject constructor(
// do the parsing and check constraints // do the parsing and check constraints
val act = actionString.split("\\s+".toRegex()).toTypedArray() val act = actionString.split("\\s+".toRegex()).toTypedArray()
if ("fillpreset" == act[0]) { ///////////////////////////////////// PRIME/FILL if ("fillpreset" == act[0]) { ///////////////////////////////////// PRIME/FILL
val amount: Double = if ("1" == act[1]) { val amount: Double = when {
sp.getDouble("fill_button1", 0.3) "1" == act[1] -> sp.getDouble("fill_button1", 0.3)
} else if ("2" == act[1]) { "2" == act[1] -> sp.getDouble("fill_button2", 0.0)
sp.getDouble("fill_button2", 0.0) "3" == act[1] -> sp.getDouble("fill_button3", 0.0)
} else if ("3" == act[1]) { else -> return
sp.getDouble("fill_button3", 0.0)
} else {
return
} }
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(amount)).value() val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
rMessage += resourceHelper.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U" rMessage += resourceHelper.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U"
@ -160,11 +158,11 @@ class ActionStringHandler @Inject constructor(
low *= Constants.MMOLL_TO_MGDL low *= Constants.MMOLL_TO_MGDL
high *= Constants.MMOLL_TO_MGDL high *= Constants.MMOLL_TO_MGDL
} }
if (low < hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0] || low > hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]) { if (low < HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0] || low > HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]) {
sendError("Min-BG out of range!") sendError("Min-BG out of range!")
return return
} }
if (high < hardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0] || high > hardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]) { if (high < HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0] || high > HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]) {
sendError("Max-BG out of range!") sendError("Max-BG out of range!")
return return
} }
@ -358,12 +356,11 @@ class ActionStringHandler @Inject constructor(
message += "Today: " + DecimalFormatter.to2Decimal(tdd) + "U " + (DecimalFormatter.to0Decimal(100 * tdd / refTDD) + "%") + "\n" message += "Today: " + DecimalFormatter.to2Decimal(tdd) + "U " + (DecimalFormatter.to0Decimal(100 * tdd / refTDD) + "%") + "\n"
message += "\n" message += "\n"
} }
var i = 0
var weighted03 = 0.0 var weighted03 = 0.0
var weighted05 = 0.0 var weighted05 = 0.0
var weighted07 = 0.0 var weighted07 = 0.0
historyList.reverse() historyList.reverse()
for (record in historyList) { for ((i, record) in historyList.withIndex()) {
val tdd = record.getTotal() val tdd = record.getTotal()
if (i == 0) { if (i == 0) {
weighted03 = tdd weighted03 = tdd
@ -374,7 +371,6 @@ class ActionStringHandler @Inject constructor(
weighted05 = weighted05 * 0.5 + tdd * 0.5 weighted05 = weighted05 * 0.5 + tdd * 0.5
weighted03 = weighted03 * 0.7 + tdd * 0.3 weighted03 = weighted03 * 0.7 + tdd * 0.3
} }
i++
} }
message += "weighted:\n" message += "weighted:\n"
message += "0.3: " + DecimalFormatter.to2Decimal(weighted03) + "U " + (DecimalFormatter.to0Decimal(100 * weighted03 / refTDD) + "%") + "\n" message += "0.3: " + DecimalFormatter.to2Decimal(weighted03) + "U " + (DecimalFormatter.to0Decimal(100 * weighted03 / refTDD) + "%") + "\n"
@ -495,7 +491,7 @@ class ActionStringHandler @Inject constructor(
//Guard from old or duplicate confirmations //Guard from old or duplicate confirmations
if (lastConfirmActionString == null) return if (lastConfirmActionString == null) return
if (lastConfirmActionString != actionString) return if (lastConfirmActionString != actionString) return
if (System.currentTimeMillis() - lastSentTimestamp > TIMEOUT) return if (System.currentTimeMillis() - lastSentTimestamp > timeout) return
lastConfirmActionString = null lastConfirmActionString = null
// do the parsing, check constraints and enact! // do the parsing, check constraints and enact!
val act = actionString.split("\\s+".toRegex()).toTypedArray() val act = actionString.split("\\s+".toRegex()).toTypedArray()
@ -578,7 +574,7 @@ class ActionStringHandler @Inject constructor(
lastConfirmActionString = rAction lastConfirmActionString = rAction
return return
} }
//send profile to pumpe //send profile to pump
activePlugin.activeTreatments.doProfileSwitch(0, percentage, timeshift) activePlugin.activeTreatments.doProfileSwitch(0, percentage, timeshift)
} }
@ -642,8 +638,8 @@ class ActionStringHandler @Inject constructor(
} }
} }
@Synchronized private fun sendError(errormessage: String) { @Synchronized private fun sendError(errorMessage: String) {
wearPlugin.requestActionConfirmation("ERROR", errormessage, "error") wearPlugin.requestActionConfirmation("ERROR", errorMessage, "error")
lastSentTimestamp = System.currentTimeMillis() lastSentTimestamp = System.currentTimeMillis()
lastConfirmActionString = null lastConfirmActionString = null
lastBolusWizard = null lastBolusWizard = null

View file

@ -56,8 +56,8 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.receivers.ReceiverStatusStore; import info.nightscout.androidaps.receivers.ReceiverStatusStore;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper; import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.GlucoseValueUtilsKt;
import info.nightscout.androidaps.utils.ToastUtils; import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.extensions.GlucoseValueUtilsKt;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -343,15 +343,15 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
boolean detailed = sp.getBoolean(R.string.key_wear_detailed_delta, false); boolean detailed = sp.getBoolean(R.string.key_wear_detailed_delta, false);
if (units.equals(Constants.MGDL)) { if (units.equals(Constants.MGDL)) {
if (detailed) { if (detailed) {
deltastring += DecimalFormatter.to1Decimal(Math.abs(deltaMGDL)); deltastring += DecimalFormatter.INSTANCE.to1Decimal(Math.abs(deltaMGDL));
} else { } else {
deltastring += DecimalFormatter.to0Decimal(Math.abs(deltaMGDL)); deltastring += DecimalFormatter.INSTANCE.to0Decimal(Math.abs(deltaMGDL));
} }
} else { } else {
if (detailed) { if (detailed) {
deltastring += DecimalFormatter.to2Decimal(Math.abs(deltaMMOL)); deltastring += DecimalFormatter.INSTANCE.to2Decimal(Math.abs(deltaMMOL));
} else { } else {
deltastring += DecimalFormatter.to1Decimal(Math.abs(deltaMMOL)); deltastring += DecimalFormatter.INSTANCE.to1Decimal(Math.abs(deltaMMOL));
} }
} }
return deltastring; return deltastring;
@ -689,14 +689,14 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
treatmentsPlugin.updateTotalIOBTempBasals(); treatmentsPlugin.updateTotalIOBTempBasals();
IobTotal basalIob = treatmentsPlugin.getLastCalculationTempBasals().round(); IobTotal basalIob = treatmentsPlugin.getLastCalculationTempBasals().round();
iobSum = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob); iobSum = DecimalFormatter.INSTANCE.to2Decimal(bolusIob.iob + basalIob.basaliob);
iobDetail = "(" + DecimalFormatter.to2Decimal(bolusIob.iob) + "|" + DecimalFormatter.to2Decimal(basalIob.basaliob) + ")"; iobDetail = "(" + DecimalFormatter.INSTANCE.to2Decimal(bolusIob.iob) + "|" + DecimalFormatter.INSTANCE.to2Decimal(basalIob.basaliob) + ")";
cobString = iobCobCalculatorPlugin.getCobInfo(false, "WatcherUpdaterService").generateCOBString(); cobString = iobCobCalculatorPlugin.getCobInfo(false, "WatcherUpdaterService").generateCOBString();
currentBasal = generateBasalString(); currentBasal = generateBasalString();
//bgi //bgi
double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits()); double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits());
bgiString = "" + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to1Decimal(bgi); bgiString = "" + ((bgi >= 0) ? "+" : "") + DecimalFormatter.INSTANCE.to1Decimal(bgi);
status = generateStatusString(profile, currentBasal, iobSum, iobDetail, bgiString); status = generateStatusString(profile, currentBasal, iobSum, iobDetail, bgiString);
} }
@ -804,7 +804,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
if (sp.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false)) { if (sp.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false)) {
basalStringResult = "100%"; basalStringResult = "100%";
} else { } else {
basalStringResult = DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h"; basalStringResult = DecimalFormatter.INSTANCE.to2Decimal(profile.getBasal()) + "U/h";
} }
} }
return basalStringResult; return basalStringResult;

View file

@ -159,7 +159,7 @@ class IobCobOref1Thread internal constructor(
aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString()) aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString())
aapsLogger.debug(LTag.AUTOSENS, bucketedData.toString()) aapsLogger.debug(LTag.AUTOSENS, bucketedData.toString())
aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.bgReadings.toString()) aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.bgReadings.toString())
val notification = Notification(Notification.SENDLOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW) val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
sp.putBoolean("log_AUTOSENS", true) sp.putBoolean("log_AUTOSENS", true)
break break
@ -182,7 +182,7 @@ class IobCobOref1Thread internal constructor(
aapsLogger.debug(autosensDataTable.toString()) aapsLogger.debug(autosensDataTable.toString())
aapsLogger.debug(bucketedData.toString()) aapsLogger.debug(bucketedData.toString())
aapsLogger.debug(iobCobCalculatorPlugin.bgReadings.toString()) aapsLogger.debug(iobCobCalculatorPlugin.bgReadings.toString())
val notification = Notification(Notification.SENDLOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW) val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
sp.putBoolean("log_AUTOSENS", true) sp.putBoolean("log_AUTOSENS", true)
break break

View file

@ -156,7 +156,7 @@ class IobCobThread @Inject internal constructor(
aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString()) aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString())
aapsLogger.debug(LTag.AUTOSENS, bucketedData.toString()) aapsLogger.debug(LTag.AUTOSENS, bucketedData.toString())
aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.bgReadings.toString()) aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.bgReadings.toString())
val notification = Notification(Notification.SENDLOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW) val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
sp.putBoolean("log_AUTOSENS", true) sp.putBoolean("log_AUTOSENS", true)
break break
@ -179,7 +179,7 @@ class IobCobThread @Inject internal constructor(
aapsLogger.debug(autosensDataTable.toString()) aapsLogger.debug(autosensDataTable.toString())
aapsLogger.debug(bucketedData.toString()) aapsLogger.debug(bucketedData.toString())
aapsLogger.debug(iobCobCalculatorPlugin.bgReadings.toString()) aapsLogger.debug(iobCobCalculatorPlugin.bgReadings.toString())
val notification = Notification(Notification.SENDLOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW) val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
sp.putBoolean("log_AUTOSENS", true) sp.putBoolean("log_AUTOSENS", true)
break break

View file

@ -22,10 +22,10 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import io.reactivex.rxkotlin.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.text.DecimalFormat import java.text.DecimalFormat
import javax.inject.Inject import javax.inject.Inject
@ -122,11 +122,11 @@ class LocalProfileFragment : DaggerFragment() {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic, "IC", resourceHelper.gs(R.string.ic_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic, "IC", resourceHelper.gs(R.string.ic_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 0.1, DecimalFormat("0.0"), save)
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
if (units == Constants.MGDL) { if (units == Constants.MGDL) {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, hardLimits.MINISF, hardLimits.MAXISF, 1.0, DecimalFormat("0"), save) TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save) TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)
} else { } else {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, Profile.fromMgdlToUnits(hardLimits.MINISF, Constants.MMOL), Profile.fromMgdlToUnits(hardLimits.MAXISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, Profile.fromMgdlToUnits(HardLimits.MIN_ISF, Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.MAX_ISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, Profile.fromMgdlToUnits(hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save) TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
} }
// Spinner // Spinner
@ -222,7 +222,7 @@ class LocalProfileFragment : DaggerFragment() {
disposable += rxBus disposable += rxBus
.toObservable(EventLocalProfileChanged::class.java) .toObservable(EventLocalProfileChanged::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribe({ build() },fabricPrivacy::logException) .subscribe({ build() }, fabricPrivacy::logException)
build() build()
} }

View file

@ -26,9 +26,9 @@ import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.directionToIcon import info.nightscout.androidaps.utils.extensions.directionToIcon
import info.nightscout.androidaps.utils.extensions.toVisibility import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.valueToUnitsString
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.plusAssign
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit

View file

@ -250,8 +250,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (!t.isValid) continue; if (!t.isValid) continue;
if (t.date > time) continue; if (t.date > time) continue;
Iob tIOB = t.iobCalc(time, dia); Iob tIOB = t.iobCalc(time, dia);
total.iob += tIOB.iobContrib; total.iob += tIOB.getIobContrib();
total.activity += tIOB.activityContrib; total.activity += tIOB.getActivityContrib();
if (t.insulin > 0 && t.date > total.lastBolusTime) if (t.insulin > 0 && t.date > total.lastBolusTime)
total.lastBolusTime = t.date; total.lastBolusTime = t.date;
if (!t.isSMB) { if (!t.isSMB) {
@ -260,7 +260,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
long timeSinceTreatment = time - t.date; long timeSinceTreatment = time - t.date;
long snoozeTime = t.date + (long) (timeSinceTreatment * sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0)); long snoozeTime = t.date + (long) (timeSinceTreatment * sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0));
Iob bIOB = t.iobCalc(snoozeTime, dia); Iob bIOB = t.iobCalc(snoozeTime, dia);
total.bolussnooze += bIOB.iobContrib; total.bolussnooze += bIOB.getIobContrib();
} }
} }
} }
@ -476,8 +476,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
treatment.date = i; treatment.date = i;
treatment.insulin = running * 5.0 / 60.0; // 5 min chunk treatment.insulin = running * 5.0 / 60.0; // 5 min chunk
Iob iob = treatment.iobCalc(time, profile.getDia()); Iob iob = treatment.iobCalc(time, profile.getDia());
total.basaliob += iob.iobContrib; total.basaliob += iob.getIobContrib();
total.activity += iob.activityContrib; total.activity += iob.getActivityContrib();
} }
return total; return total;
} }

View file

@ -130,7 +130,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
holder.binding.clone.tag = profileSwitch holder.binding.clone.tag = profileSwitch
holder.binding.name.tag = profileSwitch holder.binding.name.tag = profileSwitch
holder.binding.date.tag = profileSwitch holder.binding.date.tag = profileSwitch
holder.binding.invalid.visibility = if (profileSwitch.isValid()) View.GONE else View.VISIBLE holder.binding.invalid.visibility = if (profileSwitch.isValid) View.GONE else View.VISIBLE
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {

View file

@ -128,7 +128,7 @@ open class CommandQueue @Inject constructor(
} }
private fun executingNowError(): PumpEnactResult = private fun executingNowError(): PumpEnactResult =
PumpEnactResult(injector).success(false).enacted(false).comment(resourceHelper.gs(R.string.executingrightnow)) PumpEnactResult(injector).success(false).enacted(false).comment(R.string.executingrightnow)
override fun isRunning(type: CommandType): Boolean = performing?.commandType == type override fun isRunning(type: CommandType): Boolean = performing?.commandType == type
@ -380,7 +380,7 @@ open class CommandQueue @Inject constructor(
if (!buildHelper.isEngineeringModeOrRelease()) { if (!buildHelper.isEngineeringModeOrRelease()) {
val notification = Notification(Notification.NOT_ENG_MODE_OR_RELEASE, resourceHelper.gs(R.string.not_eng_mode_or_release), Notification.URGENT) val notification = Notification(Notification.NOT_ENG_MODE_OR_RELEASE, resourceHelper.gs(R.string.not_eng_mode_or_release), Notification.URGENT)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(resourceHelper.gs(R.string.not_eng_mode_or_release)))?.run() callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(R.string.not_eng_mode_or_release)))?.run()
return false return false
} }
*/ */
@ -390,7 +390,7 @@ open class CommandQueue @Inject constructor(
if (basalValue.value < activePlugin.get().activePump.pumpDescription.basalMinimumRate) { if (basalValue.value < activePlugin.get().activePump.pumpDescription.basalMinimumRate) {
val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, resourceHelper.gs(R.string.basalvaluebelowminimum), Notification.URGENT) val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, resourceHelper.gs(R.string.basalvaluebelowminimum), Notification.URGENT)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(resourceHelper.gs(R.string.basalvaluebelowminimum)))?.run() callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(R.string.basalvaluebelowminimum))?.run()
return false return false
} }
} }

View file

@ -91,10 +91,10 @@ class AndroidPermission @Inject constructor(
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_SMS)) } else rxBus.send(EventDismissNotification(Notification.PERMISSION_SMS))
// Following is a bug in Android 8 // Following is a bug in Android 8
if (permissionNotGranted(activity, Manifest.permission.READ_PHONE_STATE)) { if (permissionNotGranted(activity, Manifest.permission.READ_PHONE_STATE)) {
val notification = NotificationWithAction(injector, Notification.PERMISSION_PHONESTATE, resourceHelper.gs(R.string.smscommunicator_missingphonestatepermission), Notification.URGENT) val notification = NotificationWithAction(injector, Notification.PERMISSION_PHONE_STATE, resourceHelper.gs(R.string.smscommunicator_missingphonestatepermission), Notification.URGENT)
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.READ_PHONE_STATE)) } notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.READ_PHONE_STATE)) }
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_PHONESTATE)) } else rxBus.send(EventDismissNotification(Notification.PERMISSION_PHONE_STATE))
} }
} }

View file

@ -9,6 +9,8 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import kotlin.math.max
import kotlin.math.min
@Singleton @Singleton
class HardLimits @Inject constructor( class HardLimits @Inject constructor(
@ -20,98 +22,75 @@ class HardLimits @Inject constructor(
private val nsUpload: NSUpload private val nsUpload: NSUpload
) { ) {
val CHILD = 0 companion object {
val TEENAGE = 1
val ADULT = 2
val RESISTANTADULT = 3
val PREGNANT = 4
val MAXBOLUS = doubleArrayOf(5.0, 10.0, 17.0, 25.0, 60.0)
// Very Hard Limits Ranges private const val CHILD = 0
// First value is the Lowest and second value is the Highest a Limit can define private const val TEENAGE = 1
val VERY_HARD_LIMIT_MIN_BG = intArrayOf(72, 180) private const val ADULT = 2
val VERY_HARD_LIMIT_MAX_BG = intArrayOf(90, 270) private const val RESISTANT_ADULT = 3
val VERY_HARD_LIMIT_TARGET_BG = intArrayOf(80, 200) private const val PREGNANT = 4
private val MAX_BOLUS = doubleArrayOf(5.0, 10.0, 17.0, 25.0, 60.0)
// Very Hard Limits Ranges for Temp Targets // Very Hard Limits Ranges
val VERY_HARD_LIMIT_TEMP_MIN_BG = intArrayOf(72, 180) // First value is the Lowest and second value is the Highest a Limit can define
val VERY_HARD_LIMIT_TEMP_MAX_BG = intArrayOf(72, 270) val VERY_HARD_LIMIT_MIN_BG = intArrayOf(72, 180)
val VERY_HARD_LIMIT_TEMP_TARGET_BG = intArrayOf(72, 200) val VERY_HARD_LIMIT_MAX_BG = intArrayOf(90, 270)
val MINDIA = doubleArrayOf(5.0, 5.0, 5.0, 5.0, 5.0) val VERY_HARD_LIMIT_TARGET_BG = intArrayOf(80, 200)
val MAXDIA = doubleArrayOf(7.0, 7.0, 7.0, 7.0, 10.0)
val MINIC = doubleArrayOf(2.0, 2.0, 2.0, 2.0, 0.3)
val MAXIC = doubleArrayOf(100.0, 100.0, 100.0, 100.0, 100.0)
val MINISF = 2.0 // mgdl
val MAXISF = 720.0 // mgdl
val MAXIOB_AMA = doubleArrayOf(3.0, 5.0, 7.0, 12.0, 25.0)
val MAXIOB_SMB = doubleArrayOf(3.0, 7.0, 12.0, 25.0, 40.0)
val MAXBASAL = doubleArrayOf(2.0, 5.0, 10.0, 12.0, 25.0)
//LGS Hard limits // Very Hard Limits Ranges for Temp Targets
//No IOB at all val VERY_HARD_LIMIT_TEMP_MIN_BG = intArrayOf(72, 180)
val MAXIOB_LGS = 0.0 val VERY_HARD_LIMIT_TEMP_MAX_BG = intArrayOf(72, 270)
val VERY_HARD_LIMIT_TEMP_TARGET_BG = intArrayOf(72, 200)
val MIN_DIA = doubleArrayOf(5.0, 5.0, 5.0, 5.0, 5.0)
val MAX_DIA = doubleArrayOf(7.0, 7.0, 7.0, 7.0, 10.0)
val MIN_IC = doubleArrayOf(2.0, 2.0, 2.0, 2.0, 0.3)
val MAX_IC = doubleArrayOf(100.0, 100.0, 100.0, 100.0, 100.0)
const val MIN_ISF = 2.0 // mgdl
const val MAX_ISF = 720.0 // mgdl
val MAX_IOB_AMA = doubleArrayOf(3.0, 5.0, 7.0, 12.0, 25.0)
val MAX_IOB_SMB = doubleArrayOf(3.0, 7.0, 12.0, 25.0, 40.0)
val MAX_BASAL = doubleArrayOf(2.0, 5.0, 10.0, 12.0, 25.0)
//LGS Hard limits
//No IOB at all
const val MAX_IOB_LGS = 0.0
private fun loadAge(): Int {
val sp_age = sp.getString(R.string.key_age, "")
val age: Int
age = if (sp_age == resourceHelper.gs(R.string.key_child)) CHILD
else if (sp_age == resourceHelper.gs(R.string.key_teenage)) TEENAGE
else if (sp_age == resourceHelper.gs(R.string.key_adult)) ADULT
else if (sp_age == resourceHelper.gs(R.string.key_resistantadult)) RESISTANTADULT
else if (sp_age == resourceHelper.gs(R.string.key_pregnant)) PREGNANT
else ADULT
return age
} }
fun maxBolus(): Double { private fun loadAge(): Int = when (sp.getString(R.string.key_age, "")) {
return MAXBOLUS[loadAge()] resourceHelper.gs(R.string.key_child) -> CHILD
resourceHelper.gs(R.string.key_teenage) -> TEENAGE
resourceHelper.gs(R.string.key_adult) -> ADULT
resourceHelper.gs(R.string.key_resistantadult) -> RESISTANT_ADULT
resourceHelper.gs(R.string.key_pregnant) -> PREGNANT
else -> ADULT
} }
fun maxIobAMA(): Double { fun maxBolus(): Double = MAX_BOLUS[loadAge()]
return MAXIOB_AMA[loadAge()] fun maxIobAMA(): Double = MAX_IOB_AMA[loadAge()]
} fun maxIobSMB(): Double = MAX_IOB_SMB[loadAge()]
fun maxBasal(): Double = MAX_BASAL[loadAge()]
fun maxIobSMB(): Double { fun minDia(): Double = MIN_DIA[loadAge()]
return MAXIOB_SMB[loadAge()] fun maxDia(): Double = MAX_DIA[loadAge()]
} fun minIC(): Double = MIN_IC[loadAge()]
fun maxIC(): Double = MAX_IC[loadAge()]
fun maxBasal(): Double {
return MAXBASAL[loadAge()]
}
fun minDia(): Double {
return MINDIA[loadAge()]
}
fun maxDia(): Double {
return MAXDIA[loadAge()]
}
fun minIC(): Double {
return MINIC[loadAge()]
}
fun maxIC(): Double {
return MAXIC[loadAge()]
}
// safety checks // safety checks
fun checkOnlyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean { fun checkOnlyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean =
return value == verifyHardLimits(value, valueName, lowLimit, highLimit) value == verifyHardLimits(value, valueName, lowLimit, highLimit)
}
fun verifyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Double { fun verifyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Double {
var newvalue = value var newValue = value
if (newvalue < lowLimit || newvalue > highLimit) { if (newValue < lowLimit || newValue > highLimit) {
newvalue = Math.max(newvalue, lowLimit) newValue = max(newValue, lowLimit)
newvalue = Math.min(newvalue, highLimit) newValue = min(newValue, highLimit)
var msg = String.format(resourceHelper.gs(R.string.valueoutofrange), resourceHelper.gs(valueName)) var msg = String.format(resourceHelper.gs(R.string.valueoutofrange), resourceHelper.gs(valueName))
msg += ".\n" msg += ".\n"
msg += String.format(resourceHelper.gs(R.string.valuelimitedto), value, newvalue) msg += String.format(resourceHelper.gs(R.string.valuelimitedto), value, newValue)
aapsLogger.error(msg) aapsLogger.error(msg)
nsUpload.uploadError(msg) nsUpload.uploadError(msg)
ToastUtils.showToastInUiThread(context, rxBus, msg, R.raw.error) ToastUtils.showToastInUiThread(context, rxBus, msg, R.raw.error)
} }
return newvalue return newValue
} }
} }

View file

@ -0,0 +1,45 @@
package info.nightscout.androidaps.utils
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TrendCalculator @Inject constructor(
private val repository: AppRepository
) {
fun getTrendArrow(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow =
if (glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE) glucoseValue.trendArrow
else calculateDirection(glucoseValue)
private fun calculateDirection(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow {
val toTime = glucoseValue.timestamp
val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet()
if (readings.size < 2)
return GlucoseValue.TrendArrow.NONE
val current = readings[0]
val previous = readings[1]
// Avoid division by 0
val slope =
if (current.timestamp == previous.timestamp) 0.0
else (previous.value - current.value) / (previous.timestamp - current.timestamp)
val slopeByMinute = slope * 60000
return when {
slopeByMinute <= -3.5 -> GlucoseValue.TrendArrow.DOUBLE_DOWN
slopeByMinute <= -2 -> GlucoseValue.TrendArrow.SINGLE_DOWN
slopeByMinute <= -1 -> GlucoseValue.TrendArrow.FORTY_FIVE_DOWN
slopeByMinute <= 1 -> GlucoseValue.TrendArrow.FLAT
slopeByMinute <= 2 -> GlucoseValue.TrendArrow.FORTY_FIVE_UP
slopeByMinute <= 3.5 -> GlucoseValue.TrendArrow.SINGLE_UP
slopeByMinute <= 40 -> GlucoseValue.TrendArrow.DOUBLE_UP
else -> GlucoseValue.TrendArrow.NONE
}
}
}

View file

@ -1,7 +1,8 @@
package info.nightscout.androidaps.utils package info.nightscout.androidaps.utils.extensions
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.utils.DecimalFormatter
fun GlucoseValue.valueToUnits(units: String): Double = fun GlucoseValue.valueToUnits(units: String): Double =
if (units == Constants.MGDL) value if (units == Constants.MGDL) value

View file

@ -12,7 +12,7 @@ class TabPageAdapter(private val activity: AppCompatActivity) : FragmentStateAda
override fun getItemCount(): Int = visibleFragmentList.size override fun getItemCount(): Int = visibleFragmentList.size
override fun createFragment(position: Int): Fragment = override fun createFragment(position: Int): Fragment =
activity.supportFragmentManager.fragmentFactory.instantiate(ClassLoader.getSystemClassLoader(), visibleFragmentList[position].pluginDescription.fragmentClass) activity.supportFragmentManager.fragmentFactory.instantiate(ClassLoader.getSystemClassLoader(), visibleFragmentList[position].pluginDescription.fragmentClass ?: Fragment::class.java.name)
fun getPluginAt(position: Int): PluginBase = visibleFragmentList[position] fun getPluginAt(position: Int): PluginBase = visibleFragmentList[position]

View file

@ -15,8 +15,8 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
import info.nightscout.androidaps.utils.JsonHelper.safeGetString import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import info.nightscout.androidaps.utils.valueToUnits
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import java.util.* import java.util.*
@ -79,7 +79,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
fun doCalc(profile: Profile, profileName: String, lastBG: GlucoseValue, _synchronized: Boolean): BolusWizard { fun doCalc(profile: Profile, profileName: String, lastBG: GlucoseValue, _synchronized: Boolean): BolusWizard {
val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet() val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet()
val tempTarget = if (dbRecord is ValueWrapper.Existing) dbRecord.value else null val tempTarget = if (dbRecord is ValueWrapper.Existing) dbRecord.value else null
//BG //BG
var bg = 0.0 var bg = 0.0
if (useBG() == YES) { if (useBG() == YES) {

View file

@ -77,16 +77,19 @@
<TableLayout <TableLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:paddingEnd="5dp"> android:paddingEnd="5dp">
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="1"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
@ -97,6 +100,8 @@
android:paddingLeft="10dp" android:paddingLeft="10dp"
android:paddingRight="10dp" android:paddingRight="10dp"
android:text="@string/time_offset" android:text="@string/time_offset"
android:gravity="center_vertical"
android:layout_weight="1"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="bold" /> android:textStyle="bold" />
@ -115,11 +120,6 @@
android:padding="2dp" /> android:padding="2dp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<info.nightscout.androidaps.utils.ui.MinutesNumberPicker <info.nightscout.androidaps.utils.ui.MinutesNumberPicker
android:id="@+id/time" android:id="@+id/time"
android:layout_width="130dp" android:layout_width="130dp"
@ -135,80 +135,57 @@
android:text="@string/unit_minute_short" android:text="@string/unit_minute_short"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</TableRow> </TableRow>
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<LinearLayout <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_weight="1"
android:padding="10dp"
android:width="120dp"
android:text="@string/careportal_newnstreatment_duration_label"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="bold" />
<TextView <info.nightscout.androidaps.utils.ui.NumberPicker
android:layout_width="wrap_content" android:id="@+id/duration"
android:layout_height="wrap_content" android:layout_width="130dp"
android:layout_gravity="center" android:layout_height="40dp"
android:width="120dp" android:layout_gravity="center_horizontal" />
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/careportal_newnstreatment_duration_label"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="bold" />
</LinearLayout> <TextView
<LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_gravity="center_vertical"
android:gravity="start"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/shorthour"
android:textAppearance="?android:attr/textAppearanceSmall" />
<info.nightscout.androidaps.utils.ui.NumberPicker
android:id="@+id/duration"
android:layout_width="130dp"
android:layout_height="40dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="start"
android:minWidth="45dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/shorthour"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</TableRow> </TableRow>
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_weight="1"
android:padding="10dp"
android:width="120dp" android:width="120dp"
android:paddingLeft="10dp" android:paddingLeft="10dp"
android:paddingRight="10dp" android:paddingRight="10dp"
android:text="@string/treatments_wizard_carbs_label" android:text="@string/treatments_wizard_carbs_label"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<info.nightscout.androidaps.utils.ui.NumberPicker <info.nightscout.androidaps.utils.ui.NumberPicker
android:id="@+id/carbs" android:id="@+id/carbs"
@ -218,7 +195,6 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="start" android:gravity="start"
android:minWidth="45dp" android:minWidth="45dp"
android:paddingStart="5dp" android:paddingStart="5dp"
@ -226,7 +202,6 @@
android:text="@string/shortgramm" android:text="@string/shortgramm"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</TableRow> </TableRow>
</TableLayout> </TableLayout>

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.dana.DanaPump
import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
@ -41,6 +42,8 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.`when` import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.anyString
import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
import java.util.* import java.util.*
@ -91,6 +94,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
if (it is Objective) { if (it is Objective) {
it.sp = sp it.sp = sp
} }
if (it is PumpEnactResult) {
it.resourceHelper = resourceHelper
}
} }
} }
@ -115,6 +121,15 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
`when`(resourceHelper.gs(R.string.limitingiob)).thenReturn("Limiting IOB to %.1f U because of %s") `when`(resourceHelper.gs(R.string.limitingiob)).thenReturn("Limiting IOB to %.1f U because of %s")
`when`(resourceHelper.gs(R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s") `when`(resourceHelper.gs(R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
`when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s") `when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
`when`(resourceHelper.gs(R.string.itmustbepositivevalue)).thenReturn("it must be positive value")
`when`(resourceHelper.gs(R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
`when`(resourceHelper.gs(R.string.pumplimit)).thenReturn("pump limit")
`when`(resourceHelper.gs(R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
`when`(resourceHelper.gs(R.string.limitingpercentrate, 0, "it must be positive value")).thenReturn("")
`when`(resourceHelper.gs(R.string.limitingbolus, 3.0, "pump limit")).thenReturn("")
`when`(resourceHelper.gs(R.string.limitingbolus, 6.0, "pump limit")).thenReturn("")
`when`(resourceHelper.gs(R.string.limitingbasalratio, 0.8, "pump limit")).thenReturn("")
`when`(resourceHelper.gs(R.string.limitingpercentrate, 200, "pump limit")).thenReturn("")
// RS constructor // RS constructor
`when`(sp.getString(R.string.key_danars_address, "")).thenReturn("") `when`(sp.getString(R.string.key_danars_address, "")).thenReturn("")

View file

@ -16,7 +16,6 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert
@ -50,15 +49,13 @@ class LoopPluginTest : TestBase() {
@Mock lateinit var nsUpload: NSUpload @Mock lateinit var nsUpload: NSUpload
@Mock lateinit var notificationManager: NotificationManager @Mock lateinit var notificationManager: NotificationManager
@Mock lateinit var databaseHelper: DatabaseHelperInterface @Mock lateinit var databaseHelper: DatabaseHelperInterface
private lateinit var hardLimits: HardLimits
private lateinit var loopPlugin: LoopPlugin private lateinit var loopPlugin: LoopPlugin
val injector = HasAndroidInjector { AndroidInjector { } } val injector = HasAndroidInjector { AndroidInjector { } }
@Before fun prepareMock() { @Before fun prepareMock() {
hardLimits = HardLimits(aapsLogger, rxBus, sp, resourceHelper, context, nsUpload)
loopPlugin = LoopPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, Config(), constraintChecker, resourceHelper, profileFunction, context, commandQueue, activePlugin, treatmentsPlugin, virtualPumpPlugin, iobCobCalculatorPlugin, receiverStatusStore, fabricPrivacy, nsUpload, databaseHelper, hardLimits) loopPlugin = LoopPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, Config(), constraintChecker, resourceHelper, profileFunction, context, commandQueue, activePlugin, treatmentsPlugin, virtualPumpPlugin, iobCobCalculatorPlugin, receiverStatusStore, fabricPrivacy, nsUpload, databaseHelper)
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin) `when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(context.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager) `when`(context.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager)
} }

View file

@ -49,7 +49,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
private lateinit var safetyPlugin: SafetyPlugin private lateinit var safetyPlugin: SafetyPlugin
val injector = HasAndroidInjector { AndroidInjector { } } val injector = HasAndroidInjector { AndroidInjector { } }
val pumpDescription = PumpDescription() private val pumpDescription = PumpDescription()
@Before @Before
fun prepare() { fun prepare() {
@ -198,7 +198,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(R.string.key_age, "")).thenReturn("child") `when`(sp.getString(R.string.key_age, "")).thenReturn("child")
var d = Constraint(Constants.REALLYHIGHBOLUS) var d = Constraint(Constants.REALLYHIGHBOLUS)
d = safetyPlugin.applyBolusConstraints(d) d = safetyPlugin.applyBolusConstraints(d)
Assert.assertEquals(3.0, d.value()!!, 0.01) Assert.assertEquals(3.0, d.value(), 0.01)
Assert.assertEquals(""" Assert.assertEquals("""
Safety: Limiting bolus to 3.0 U because of max value in preferences Safety: Limiting bolus to 3.0 U because of max value in preferences
Safety: Limiting bolus to 5.0 U because of hard limit Safety: Limiting bolus to 5.0 U because of hard limit
@ -240,7 +240,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
// Apply all limits // Apply all limits
var d = Constraint(Constants.REALLYHIGHIOB) var d = Constraint(Constants.REALLYHIGHIOB)
d = safetyPlugin.applyMaxIOBConstraints(d) d = safetyPlugin.applyMaxIOBConstraints(d)
Assert.assertEquals(1.5, d.value()!!, 0.01) Assert.assertEquals(1.5, d.value(), 0.01)
Assert.assertEquals(""" Assert.assertEquals("""
Safety: Limiting IOB to 1.5 U because of max value in preferences Safety: Limiting IOB to 1.5 U because of max value in preferences
""".trimIndent(), d.getReasons(aapsLogger)) """.trimIndent(), d.getReasons(aapsLogger))

View file

@ -12,6 +12,9 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.anyLong
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@ -24,6 +27,7 @@ class StorageConstraintPluginTest : TestBase() {
@Before fun prepareMock() { @Before fun prepareMock() {
storageConstraintPlugin = StorageConstraintPlugin({ AndroidInjector { } }, aapsLogger, resourceHelper, rxBusWrapper) storageConstraintPlugin = StorageConstraintPlugin({ AndroidInjector { } }, aapsLogger, resourceHelper, rxBusWrapper)
`when`(resourceHelper.gs(anyInt(), anyLong())).thenReturn("")
} }
class MockedStorageConstraintPlugin constructor( class MockedStorageConstraintPlugin constructor(

View file

@ -83,7 +83,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
var injector: HasAndroidInjector = HasAndroidInjector { var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
if (it is PumpEnactResult) { if (it is PumpEnactResult) {
it.aapsLogger = aapsLogger
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
} }
if (it is AuthRequest) { if (it is AuthRequest) {

View file

@ -8,7 +8,6 @@ import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.SensitivityInterface import info.nightscout.androidaps.interfaces.SensitivityInterface
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONObject import org.json.JSONObject
@ -25,7 +24,7 @@ class AbstractSensitivityPluginTest : TestBase() {
@Mock lateinit var resourceHelper: ResourceHelper @Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var sp: SP @Mock lateinit var sp: SP
private inner class SensitivityTestClass(pluginDescription: PluginDescription, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, sp: SP) : AbstractSensitivityPlugin(pluginDescription, HasAndroidInjector { AndroidInjector { Unit } }, aapsLogger, resourceHelper, sp) { private inner class SensitivityTestClass(pluginDescription: PluginDescription, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, sp: SP) : AbstractSensitivityPlugin(pluginDescription, HasAndroidInjector { AndroidInjector { } }, aapsLogger, resourceHelper, sp) {
override fun detectSensitivity(plugin: IobCobCalculatorInterface, fromTime: Long, toTime: Long): AutosensResult { override fun detectSensitivity(plugin: IobCobCalculatorInterface, fromTime: Long, toTime: Long): AutosensResult {
return AutosensResult() return AutosensResult()

View file

@ -8,6 +8,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraint
@ -120,6 +121,7 @@ class CommandQueueTest : TestBaseWithProfile() {
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint) `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint)
val percentageConstraint = Constraint(0) val percentageConstraint = Constraint(0)
`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint) `when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint)
`when`(resourceHelper.gs(R.string.connectiontimedout)).thenReturn("Connection timed out")
} }
@Test @Test

View file

@ -41,7 +41,6 @@ class ActionAlarmTest : TestBase() {
it.timerUtil = timerUtil it.timerUtil = timerUtil
} }
if (it is PumpEnactResult) { if (it is PumpEnactResult) {
it.aapsLogger = aapsLogger
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
} }
} }

View file

@ -38,7 +38,6 @@ class ActionNotificationTest : TestBase() {
it.nsUpload = nsUpload it.nsUpload = nsUpload
} }
if (it is PumpEnactResult) { if (it is PumpEnactResult) {
it.aapsLogger = aapsLogger
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
} }
} }

View file

@ -108,7 +108,6 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.rxBus = rxBus it.rxBus = rxBus
} }
if (it is PumpEnactResult) { if (it is PumpEnactResult) {
it.aapsLogger = aapsLogger
it.resourceHelper = resourceHelper it.resourceHelper = resourceHelper
} }
if (it is InputTempTarget) { if (it is InputTempTarget) {

View file

@ -6,7 +6,6 @@ import android.os.SystemClock;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
@ -166,7 +165,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
super.onStart(); super.onStart();
ruffyScripter = new RuffyScripter(context); ruffyScripter = new RuffyScripter(context);
OPERATION_NOT_SUPPORTED = new PumpEnactResult(getInjector()) OPERATION_NOT_SUPPORTED = new PumpEnactResult(getInjector())
.success(false).enacted(false).comment(getResourceHelper().gs(R.string.combo_pump_unsupported_operation)); .success(false).enacted(false).comment(R.string.combo_pump_unsupported_operation);
} }
public ComboPump getPump() { public ComboPump getPump() {
@ -252,35 +251,35 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
getAapsLogger().error("setNewBasalProfile not initialized"); getAapsLogger().error("setNewBasalProfile not initialized");
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, getResourceHelper().gs(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT); Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, getResourceHelper().gs(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
rxBus.send(new EventNewNotification(notification)); rxBus.send(new EventNewNotification(notification));
return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(getResourceHelper().gs(R.string.pumpNotInitializedProfileNotSet)); return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(R.string.pumpNotInitializedProfileNotSet);
} }
BasalProfile requestedBasalProfile = convertProfileToComboProfile(profile); BasalProfile requestedBasalProfile = convertProfileToComboProfile(profile);
if (pump.basalProfile.equals(requestedBasalProfile)) { if (pump.basalProfile.equals(requestedBasalProfile)) {
//dismiss previously "FAILED" overview notifications //dismiss previously "FAILED" overview notifications
rxBus.send(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); rxBus.send(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
rxBus.send(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); rxBus.send(new EventDismissNotification(Notification.FAILED_UPDATE_PROFILE));
return new PumpEnactResult(getInjector()).success(true).enacted(false); return new PumpEnactResult(getInjector()).success(true).enacted(false);
} }
CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState); CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState);
if (stateResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) { if (stateResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) {
return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(getResourceHelper().gs(R.string.combo_force_disabled_notification)); return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(R.string.combo_force_disabled_notification);
} }
CommandResult setResult = runCommand(getResourceHelper().gs(R.string.combo_activity_setting_basal_profile), 2, CommandResult setResult = runCommand(getResourceHelper().gs(R.string.combo_activity_setting_basal_profile), 2,
() -> ruffyScripter.setBasalProfile(requestedBasalProfile)); () -> ruffyScripter.setBasalProfile(requestedBasalProfile));
if (!setResult.success) { if (!setResult.success) {
Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, getResourceHelper().gs(R.string.failedupdatebasalprofile), Notification.URGENT); Notification notification = new Notification(Notification.FAILED_UPDATE_PROFILE, getResourceHelper().gs(R.string.failedupdatebasalprofile), Notification.URGENT);
rxBus.send(new EventNewNotification(notification)); rxBus.send(new EventNewNotification(notification));
return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(getResourceHelper().gs(R.string.failedupdatebasalprofile)); return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(R.string.failedupdatebasalprofile);
} }
pump.basalProfile = requestedBasalProfile; pump.basalProfile = requestedBasalProfile;
//dismiss previously "FAILED" overview notifications //dismiss previously "FAILED" overview notifications
rxBus.send(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); rxBus.send(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
rxBus.send(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); rxBus.send(new EventDismissNotification(Notification.FAILED_UPDATE_PROFILE));
//issue success notification //issue success notification
Notification notification = new Notification(Notification.PROFILE_SET_OK, getResourceHelper().gs(R.string.profile_set_ok), Notification.INFO, 60); Notification notification = new Notification(Notification.PROFILE_SET_OK, getResourceHelper().gs(R.string.profile_set_ok), Notification.INFO, 60);
rxBus.send(new EventNewNotification(notification)); rxBus.send(new EventNewNotification(notification));
@ -375,7 +374,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
Notification n = new Notification(Notification.COMBO_PUMP_ALARM, Notification n = new Notification(Notification.COMBO_PUMP_ALARM,
getResourceHelper().gs(R.string.combo_force_disabled_notification), getResourceHelper().gs(R.string.combo_force_disabled_notification),
Notification.URGENT); Notification.URGENT);
n.soundId = R.raw.alarm; n.setSoundId(R.raw.alarm);
rxBus.send(new EventNewNotification(n)); rxBus.send(new EventNewNotification(n));
return; return;
} }
@ -480,7 +479,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
getAapsLogger().error("deliverTreatment: Invalid input"); getAapsLogger().error("deliverTreatment: Invalid input");
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.bolusDelivered(0d).carbsDelivered(0d) .bolusDelivered(0d).carbsDelivered(0d)
.comment(getResourceHelper().gs(R.string.invalidinput)); .comment(R.string.invalidinput);
} else if (detailedBolusInfo.insulin > 0) { } else if (detailedBolusInfo.insulin > 0) {
// bolus needed, ask pump to deliver it // bolus needed, ask pump to deliver it
return deliverBolus(detailedBolusInfo); return deliverBolus(detailedBolusInfo);
@ -496,7 +495,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
return new PumpEnactResult(getInjector()).success(true).enacted(true) return new PumpEnactResult(getInjector()).success(true).enacted(true)
.bolusDelivered(0d).carbsDelivered(detailedBolusInfo.carbs) .bolusDelivered(0d).carbsDelivered(detailedBolusInfo.carbs)
.comment(getResourceHelper().gs(R.string.virtualpump_resultok)); .comment(R.string.virtualpump_resultok);
} }
} finally { } finally {
rxBus.send(new EventComboPumpUpdateGUI()); rxBus.send(new EventComboPumpUpdateGUI());
@ -513,16 +512,16 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
CommandResult stateResult = runCommand(null, 2, () -> ruffyScripter.readQuickInfo(1)); CommandResult stateResult = runCommand(null, 2, () -> ruffyScripter.readQuickInfo(1));
if (!stateResult.success) { if (!stateResult.success) {
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.comment(getResourceHelper().gs(R.string.combo_error_no_connection_no_bolus_delivered)); .comment(R.string.combo_error_no_connection_no_bolus_delivered);
} }
if (stateResult.reservoirLevel != -1 && stateResult.reservoirLevel - 0.5 < detailedBolusInfo.insulin) { if (stateResult.reservoirLevel != -1 && stateResult.reservoirLevel - 0.5 < detailedBolusInfo.insulin) {
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.comment(getResourceHelper().gs(R.string.combo_reservoir_level_insufficient_for_bolus)); .comment(R.string.combo_reservoir_level_insufficient_for_bolus);
} }
// the commands above ensured a connection was made, which updated this field // the commands above ensured a connection was made, which updated this field
if (pumpHistoryChanged) { if (pumpHistoryChanged) {
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.comment(getResourceHelper().gs(R.string.combo_bolus_rejected_due_to_pump_history_change)); .comment(R.string.combo_bolus_rejected_due_to_pump_history_change);
} }
Bolus previousBolus = stateResult.history != null && !stateResult.history.bolusHistory.isEmpty() Bolus previousBolus = stateResult.history != null && !stateResult.history.bolusHistory.isEmpty()
@ -535,7 +534,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
&& previousBolus.timestamp + 60 * 1000 > System.currentTimeMillis()) { && previousBolus.timestamp + 60 * 1000 > System.currentTimeMillis()) {
getAapsLogger().debug(LTag.PUMP, "Bolus request rejected, same bolus was successfully delivered very recently"); getAapsLogger().debug(LTag.PUMP, "Bolus request rejected, same bolus was successfully delivered very recently");
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.comment(getResourceHelper().gs(R.string.bolus_frequency_exceeded)); .comment(R.string.bolus_frequency_exceeded);
} }
// if the last bolus was given in the current minute, wait till the pump clock moves // if the last bolus was given in the current minute, wait till the pump clock moves
@ -551,7 +550,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
} }
if (!timeCheckResult.success) { if (!timeCheckResult.success) {
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.comment(getResourceHelper().gs(R.string.combo_error_no_connection_no_bolus_delivered)); .comment(R.string.combo_error_no_connection_no_bolus_delivered);
} }
getAapsLogger().debug(LTag.PUMP, "Waiting for pump clock to advance for the next unused bolus record timestamp"); getAapsLogger().debug(LTag.PUMP, "Waiting for pump clock to advance for the next unused bolus record timestamp");
SystemClock.sleep(2000); SystemClock.sleep(2000);
@ -586,7 +585,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
CommandResult postBolusStateResult = runCommand(null, 3, () -> ruffyScripter.readQuickInfo(2)); CommandResult postBolusStateResult = runCommand(null, 3, () -> ruffyScripter.readQuickInfo(2));
if (!postBolusStateResult.success) { if (!postBolusStateResult.success) {
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.comment(getResourceHelper().gs(R.string.combo_error_bolus_verification_failed)); .comment(R.string.combo_error_bolus_verification_failed);
} }
Bolus lastPumpBolus = postBolusStateResult.history != null && !postBolusStateResult.history.bolusHistory.isEmpty() Bolus lastPumpBolus = postBolusStateResult.history != null && !postBolusStateResult.history.bolusHistory.isEmpty()
? postBolusStateResult.history.bolusHistory.get(0) ? postBolusStateResult.history.bolusHistory.get(0)
@ -600,14 +599,14 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
return new PumpEnactResult(getInjector()) return new PumpEnactResult(getInjector())
.success(false) .success(false)
.enacted(false) .enacted(false)
.comment(getResourceHelper().gs(R.string.combo_error_no_bolus_delivered)); .comment(R.string.combo_error_no_bolus_delivered);
} }
} }
// at least some insulin delivered, so add it to treatments // at least some insulin delivered, so add it to treatments
if (!addBolusToTreatments(detailedBolusInfo, lastPumpBolus)) if (!addBolusToTreatments(detailedBolusInfo, lastPumpBolus))
return new PumpEnactResult(getInjector()).success(false).enacted(true) return new PumpEnactResult(getInjector()).success(false).enacted(true)
.comment(getResourceHelper().gs(R.string.combo_error_updating_treatment_record)); .comment(R.string.combo_error_updating_treatment_record);
// check pump bolus record has a sane timestamp // check pump bolus record has a sane timestamp
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -741,14 +740,14 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
if (pumpHistoryChanged && percent > 110) { if (pumpHistoryChanged && percent > 110) {
return new PumpEnactResult(getInjector()).success(false).enacted(false) return new PumpEnactResult(getInjector()).success(false).enacted(false)
.comment(getResourceHelper().gs(R.string.combo_high_temp_rejected_due_to_pump_history_changes)); .comment(R.string.combo_high_temp_rejected_due_to_pump_history_changes);
} }
int adjustedPercent = percent; int adjustedPercent = percent;
if (adjustedPercent > pumpDescription.maxTempPercent) { if (adjustedPercent > pumpDescription.getMaxTempPercent()) {
getAapsLogger().debug(LTag.PUMP, "Reducing requested TBR to the maximum support by the pump: " + percent + " -> " + pumpDescription.maxTempPercent); getAapsLogger().debug(LTag.PUMP, "Reducing requested TBR to the maximum support by the pump: " + percent + " -> " + pumpDescription.getMaxTempPercent());
adjustedPercent = pumpDescription.maxTempPercent; adjustedPercent = pumpDescription.getMaxTempPercent();
} }
if (adjustedPercent % 10 != 0) { if (adjustedPercent % 10 != 0) {
@ -901,7 +900,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
Notification n = new Notification(Notification.COMBO_PUMP_ALARM, Notification n = new Notification(Notification.COMBO_PUMP_ALARM,
getResourceHelper().gs(R.string.combo_force_disabled_notification), getResourceHelper().gs(R.string.combo_force_disabled_notification),
Notification.URGENT); Notification.URGENT);
n.soundId = R.raw.alarm; n.setSoundId(R.raw.alarm);
rxBus.send(new EventNewNotification(n)); rxBus.send(new EventNewNotification(n));
commandQueue.cancelTempBasal(true, null); commandQueue.cancelTempBasal(true, null);
} }
@ -949,11 +948,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
// so update the var with it, so the check routines below can work on it // so update the var with it, so the check routines below can work on it
preCheckResult = alertConfirmationResult; preCheckResult = alertConfirmationResult;
} else if (activeAlert.errorCode != null) { } else if (activeAlert.errorCode != null) {
Notification notification = new Notification(); Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, DateUtil.now(), getResourceHelper().gs(R.string.combo_is_in_error_state, activeAlert.errorCode, activeAlert.message), Notification.URGENT, 0);
notification.date = DateUtil.now();
notification.id = Notification.COMBO_PUMP_ALARM;
notification.level = Notification.URGENT;
notification.text = getResourceHelper().gs(R.string.combo_is_in_error_state, activeAlert.errorCode, activeAlert.message);
rxBus.send(new EventNewNotification(notification)); rxBus.send(new EventNewNotification(notification));
return preCheckResult.success(false); return preCheckResult.success(false);
} }
@ -1047,15 +1042,15 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
throw new IllegalArgumentException(activeAlert.toString()); throw new IllegalArgumentException(activeAlert.toString());
} }
Notification notification = new Notification(); Notification notification = new Notification();
notification.date = DateUtil.now(); notification.setDate(DateUtil.now());
notification.id = Notification.COMBO_PUMP_ALARM; notification.setId(Notification.COMBO_PUMP_ALARM);
notification.level = Notification.NORMAL; notification.setLevel(Notification.NORMAL);
if (activeAlert.warningCode == PumpWarningCodes.CARTRIDGE_LOW) { if (activeAlert.warningCode == PumpWarningCodes.CARTRIDGE_LOW) {
notification.text = getResourceHelper().gs(R.string.combo_pump_cartridge_low_warrning); notification.setText(getResourceHelper().gs(R.string.combo_pump_cartridge_low_warrning));
} else if (activeAlert.warningCode == PumpWarningCodes.BATTERY_LOW) { } else if (activeAlert.warningCode == PumpWarningCodes.BATTERY_LOW) {
notification.text = getResourceHelper().gs(R.string.combo_pump_battery_low_warrning); notification.setText(getResourceHelper().gs(R.string.combo_pump_battery_low_warrning));
} else if (activeAlert.warningCode == PumpWarningCodes.TBR_CANCELLED) { } else if (activeAlert.warningCode == PumpWarningCodes.TBR_CANCELLED) {
notification.text = getResourceHelper().gs(R.string.combo_pump_tbr_cancelled_warrning); notification.setText(getResourceHelper().gs(R.string.combo_pump_tbr_cancelled_warrning));
} }
rxBus.send(new EventNewNotification(notification)); rxBus.send(new EventNewNotification(notification));
} }
@ -1079,7 +1074,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
Notification n = new Notification(Notification.COMBO_PUMP_ALARM, Notification n = new Notification(Notification.COMBO_PUMP_ALARM,
getResourceHelper().gs(R.string.combo_low_suspend_forced_notification), getResourceHelper().gs(R.string.combo_low_suspend_forced_notification),
Notification.URGENT); Notification.URGENT);
n.soundId = R.raw.alarm; n.setSoundId(R.raw.alarm);
rxBus.send(new EventNewNotification(n)); rxBus.send(new EventNewNotification(n));
violationWarningRaisedForBolusAt = lowSuspendOnlyLoopEnforcedUntil; violationWarningRaisedForBolusAt = lowSuspendOnlyLoopEnforcedUntil;
commandQueue.cancelTempBasal(true, null); commandQueue.cancelTempBasal(true, null);
@ -1338,8 +1333,8 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
@NonNull @Override @NonNull @Override
public PumpEnactResult loadTDDs() { public PumpEnactResult loadTDDs() {
PumpEnactResult result = new PumpEnactResult(getInjector()); PumpEnactResult result = new PumpEnactResult(getInjector());
result.success = readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL)); result.success(readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL)));
if (result.success) { if (result.getSuccess()) {
List<Tdd> tdds = pump.tddHistory; List<Tdd> tdds = pump.tddHistory;
if (tdds != null) { if (tdds != null) {
HashMap<Long, TDD> map = new HashMap<>(); HashMap<Long, TDD> map = new HashMap<>();

View file

@ -5,6 +5,7 @@ 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.androidaps.combo.R import info.nightscout.androidaps.combo.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.combo.ruffyscripter.history.Bolus import info.nightscout.androidaps.plugins.pump.combo.ruffyscripter.history.Bolus
@ -34,6 +35,9 @@ class ComboPluginTest : TestBase() {
val injector = HasAndroidInjector { val injector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
if (it is PumpEnactResult) {
it.resourceHelper = resourceHelper
}
} }
} }
@ -42,6 +46,7 @@ class ComboPluginTest : TestBase() {
@Before @Before
fun prepareMocks() { fun prepareMocks() {
`when`(resourceHelper.gs(R.string.novalidbasalrate)).thenReturn("No valid basal rate read from pump") `when`(resourceHelper.gs(R.string.novalidbasalrate)).thenReturn("No valid basal rate read from pump")
`when`(resourceHelper.gs(R.string.combo_pump_unsupported_operation)).thenReturn("Requested operation not supported by pump")
comboPlugin = ComboPlugin(injector, aapsLogger, RxBusWrapper(aapsSchedulers), resourceHelper, profileFunction, treatmentsPlugin, sp, commandQueue, context, databaseHelper) comboPlugin = ComboPlugin(injector, aapsLogger, RxBusWrapper(aapsSchedulers), resourceHelper, profileFunction, treatmentsPlugin, sp, commandQueue, context, databaseHelper)
} }

View file

@ -1,96 +0,0 @@
package info.nightscout.androidaps.data;
import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.interfaces.Interval;
/**
* Created by mike on 09.05.2017.
*/
// Zero duration means end of interval
public abstract class Intervals<T extends Interval> {
LongSparseArray<T> rawData; // oldest at index 0
public Intervals() {
rawData = new LongSparseArray<T>();
}
public synchronized Intervals<T> reset() {
rawData = new LongSparseArray<T>();
return this;
}
protected abstract void merge();
/**
* The List must be sorted by `T.start()` in ascending order
*/
public synchronized void add(List<T> list) {
for (T interval : list) {
rawData.put(interval.start(), interval);
}
merge();
}
public synchronized void add(T interval) {
rawData.put(interval.start(), interval);
merge();
}
public synchronized List<T> getList() {
List<T> list = new ArrayList<>();
for (int i = 0; i < rawData.size(); i++)
list.add(rawData.valueAt(i));
return list;
}
public synchronized List<T> getReversedList() {
List<T> list = new ArrayList<>();
for (int i = rawData.size() - 1; i >= 0; i--)
list.add(rawData.valueAt(i));
return list;
}
protected synchronized int binarySearch(long value) {
int lo = 0;
int hi = rawData.size() - 1;
while (lo <= hi) {
final int mid = (lo + hi) >>> 1;
final Interval midVal = rawData.valueAt(mid);
if (midVal.before(value)) {
lo = mid + 1;
} else if (midVal.after(value)) {
hi = mid - 1;
} else if (midVal.match(value)) {
return mid; // value found
}
}
return ~lo; // value not present
}
public abstract T getValueByInterval(long time);
public synchronized int size() {
return rawData.size();
}
public synchronized T get(int index) {
return rawData.valueAt(index);
}
public synchronized T getReversed(int index) {
return rawData.valueAt(size() - 1 - index);
}
}

View file

@ -0,0 +1,72 @@
package info.nightscout.androidaps.data
import androidx.collection.LongSparseArray
import info.nightscout.androidaps.interfaces.Interval
import java.util.*
/**
* Created by mike on 09.05.2017.
*/
// Zero duration means end of interval
abstract class Intervals<T : Interval> {
var rawData: LongSparseArray<T> = LongSparseArray()// oldest at index 0
@Synchronized fun reset(): Intervals<T> {
rawData = LongSparseArray()
return this
}
protected abstract fun merge()
/**
* The List must be sorted by `T.start()` in ascending order
*/
@Synchronized fun add(list: List<T>) {
for (interval in list) {
rawData.put(interval.start(), interval)
}
merge()
}
@Synchronized fun add(interval: T) {
rawData.put(interval.start(), interval)
merge()
}
@get:Synchronized val list: List<T>
get() {
val list: MutableList<T> = ArrayList()
for (i in 0 until rawData.size()) list.add(rawData.valueAt(i))
return list
}
@get:Synchronized val reversedList: List<T>
get() {
val list: MutableList<T> = ArrayList()
for (i in rawData.size() - 1 downTo 0) list.add(rawData.valueAt(i))
return list
}
@Synchronized protected fun binarySearch(value: Long): Int {
var lo = 0
var hi = rawData.size() - 1
while (lo <= hi) {
val mid = lo + hi ushr 1
val midVal: Interval = rawData.valueAt(mid)
when {
midVal.before(value) -> lo = mid + 1
midVal.after(value) -> hi = mid - 1
midVal.match(value) -> return mid // value found
}
}
return lo.inv() // value not present
}
abstract fun getValueByInterval(time: Long): T?
@Synchronized fun size(): Int = rawData.size()
@Synchronized operator fun get(index: Int): T? = rawData.valueAt(index)
@Synchronized fun getReversed(index: Int): T = rawData.valueAt(size() - 1 - index)
}

View file

@ -1,47 +0,0 @@
package info.nightscout.androidaps.data;
/**
* Created by mike on 05.06.2016.
*/
public class Iob {
public double iobContrib = 0d;
public double activityContrib = 0d;
public Iob iobContrib(double iobContrib) {
this.iobContrib = iobContrib;
return this;
}
public Iob activityContrib(double activityContrib) {
this.activityContrib = activityContrib;
return this;
}
public Iob plus(Iob iob) {
iobContrib += iob.iobContrib;
activityContrib += iob.activityContrib;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Iob iob = (Iob) o;
if (Double.compare(iob.iobContrib, iobContrib) != 0) return false;
return Double.compare(iob.activityContrib, activityContrib) == 0;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(iobContrib);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(activityContrib);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
}

View file

@ -0,0 +1,40 @@
package info.nightscout.androidaps.data
class Iob {
var iobContrib = 0.0
var activityContrib = 0.0
fun iobContrib(iobContrib: Double): Iob {
this.iobContrib = iobContrib
return this
}
fun activityContrib(activityContrib: Double): Iob {
this.activityContrib = activityContrib
return this
}
operator fun plus(iob: Iob): Iob {
iobContrib += iob.iobContrib
activityContrib += iob.activityContrib
return this
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val iob = other as Iob
return if (iob.iobContrib.compareTo(iobContrib) != 0) false
else iob.activityContrib.compareTo(activityContrib) == 0
}
override fun hashCode(): Int {
var result: Int
var temp: Long = java.lang.Double.doubleToLongBits(iobContrib)
result = (temp xor (temp ushr 32)).toInt()
temp = java.lang.Double.doubleToLongBits(activityContrib)
result = 31 * result + (temp xor (temp ushr 32)).toInt()
return result
}
}

View file

@ -1,190 +0,0 @@
package info.nightscout.androidaps.data;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Date;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.Round;
public class IobTotal implements DataPointWithLabelInterface {
public double iob;
public double activity;
public double bolussnooze;
public double basaliob;
public double netbasalinsulin;
public double hightempinsulin;
// oref1
public long lastBolusTime;
public IobTotal iobWithZeroTemp;
public double netInsulin = 0d; // for calculations from temp basals only
public double netRatio = 0d; // net ratio at start of temp basal
public double extendedBolusInsulin = 0d; // total insulin for extended bolus
long time;
public IobTotal copy() {
IobTotal i = new IobTotal(time);
i.iob = iob;
i.activity = activity;
i.bolussnooze = bolussnooze;
i.basaliob = basaliob;
i.netbasalinsulin = netbasalinsulin;
i.hightempinsulin = hightempinsulin;
i.lastBolusTime = lastBolusTime;
if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp.copy();
i.netInsulin = netInsulin;
i.netRatio = netRatio;
i.extendedBolusInsulin = extendedBolusInsulin;
return i;
}
public IobTotal(long time) {
this.iob = 0d;
this.activity = 0d;
this.bolussnooze = 0d;
this.basaliob = 0d;
this.netbasalinsulin = 0d;
this.hightempinsulin = 0d;
this.lastBolusTime = 0;
this.time = time;
}
public IobTotal plus(IobTotal other) {
iob += other.iob;
activity += other.activity;
bolussnooze += other.bolussnooze;
basaliob += other.basaliob;
netbasalinsulin += other.netbasalinsulin;
hightempinsulin += other.hightempinsulin;
netInsulin += other.netInsulin;
extendedBolusInsulin += other.extendedBolusInsulin;
return this;
}
public static IobTotal combine(IobTotal bolusIOB, IobTotal basalIob) {
IobTotal result = new IobTotal(bolusIOB.time);
result.iob = bolusIOB.iob + basalIob.basaliob;
result.activity = bolusIOB.activity + basalIob.activity;
result.bolussnooze = bolusIOB.bolussnooze;
result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin;
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin;
result.lastBolusTime = bolusIOB.lastBolusTime;
result.iobWithZeroTemp = basalIob.iobWithZeroTemp;
return result;
}
public IobTotal round() {
this.iob = Round.roundTo(this.iob, 0.001);
this.activity = Round.roundTo(this.activity, 0.0001);
this.bolussnooze = Round.roundTo(this.bolussnooze, 0.0001);
this.basaliob = Round.roundTo(this.basaliob, 0.001);
this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001);
this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001);
this.netInsulin = Round.roundTo(this.netInsulin, 0.001);
this.extendedBolusInsulin = Round.roundTo(this.extendedBolusInsulin, 0.001);
return this;
}
public JSONObject json() {
JSONObject json = new JSONObject();
try {
json.put("iob", iob);
json.put("basaliob", basaliob);
json.put("activity", activity);
json.put("time", DateUtil.toISOString(new Date()));
} catch (JSONException ignored) {
}
return json;
}
public JSONObject determineBasalJson() {
JSONObject json = new JSONObject();
try {
json.put("iob", iob);
json.put("basaliob", basaliob);
json.put("bolussnooze", bolussnooze);
json.put("activity", activity);
json.put("lastBolusTime", lastBolusTime);
json.put("time", DateUtil.toISOString(new Date(time)));
/*
This is requested by SMB determine_basal but by based on Scott's info
it's MDT specific safety check only
It's causing rounding issues in determine_basal
JSONObject lastTemp = new JSONObject();
lastTemp.put("date", lastTempDate);
lastTemp.put("rate", lastTempRate);
lastTemp.put("duration", lastTempDuration);
json.put("lastTemp", lastTemp);
*/
if (iobWithZeroTemp != null) {
JSONObject iwzt = iobWithZeroTemp.determineBasalJson();
json.put("iobWithZeroTemp", iwzt);
}
} catch (JSONException ignored) {
}
return json;
}
// DataPoint interface
private int color;
@Override
public double getX() {
return time;
}
@Override
public double getY() {
return iob;
}
@Override
public void setY(double y) {
}
@Override
public String getLabel() {
return null;
}
@Override
public long getDuration() {
return 0;
}
@Override
public PointsWithLabelGraphSeries.Shape getShape() {
return PointsWithLabelGraphSeries.Shape.IOBPREDICTION;
}
@Override
public float getSize() {
return 0.5f;
}
@Override
public int getColor() {
return color;
}
public IobTotal setColor(int color) {
this.color = color;
return this;
}
}

View file

@ -0,0 +1,163 @@
package info.nightscout.androidaps.data
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.Round
import org.json.JSONException
import org.json.JSONObject
import java.util.*
@Suppress("SpellCheckingInspection")
class IobTotal(var time: Long) : DataPointWithLabelInterface {
@JvmField var iob = 0.0
@JvmField var activity = 0.0
@JvmField var bolussnooze = 0.0
@JvmField var basaliob = 0.0
@JvmField var netbasalinsulin = 0.0
@JvmField var hightempinsulin = 0.0
// oref1
@JvmField var lastBolusTime: Long = 0
var iobWithZeroTemp: IobTotal? = null
@JvmField var netInsulin = 0.0 // for calculations from temp basals only
@JvmField var netRatio = 0.0 // net ratio at start of temp basal
@JvmField var extendedBolusInsulin = 0.0 // total insulin for extended bolus
fun copy(): IobTotal {
val i = IobTotal(time)
i.iob = iob
i.activity = activity
i.bolussnooze = bolussnooze
i.basaliob = basaliob
i.netbasalinsulin = netbasalinsulin
i.hightempinsulin = hightempinsulin
i.lastBolusTime = lastBolusTime
if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp!!.copy()
i.netInsulin = netInsulin
i.netRatio = netRatio
i.extendedBolusInsulin = extendedBolusInsulin
return i
}
operator fun plus(other: IobTotal): IobTotal {
iob += other.iob
activity += other.activity
bolussnooze += other.bolussnooze
basaliob += other.basaliob
netbasalinsulin += other.netbasalinsulin
hightempinsulin += other.hightempinsulin
netInsulin += other.netInsulin
extendedBolusInsulin += other.extendedBolusInsulin
return this
}
fun round(): IobTotal {
iob = Round.roundTo(iob, 0.001)
activity = Round.roundTo(activity, 0.0001)
bolussnooze = Round.roundTo(bolussnooze, 0.0001)
basaliob = Round.roundTo(basaliob, 0.001)
netbasalinsulin = Round.roundTo(netbasalinsulin, 0.001)
hightempinsulin = Round.roundTo(hightempinsulin, 0.001)
netInsulin = Round.roundTo(netInsulin, 0.001)
extendedBolusInsulin = Round.roundTo(extendedBolusInsulin, 0.001)
return this
}
fun json(): JSONObject {
val json = JSONObject()
try {
json.put("iob", iob)
json.put("basaliob", basaliob)
json.put("activity", activity)
json.put("time", DateUtil.toISOString(Date()))
} catch (ignored: JSONException) {
}
return json
}
fun determineBasalJson(): JSONObject {
val json = JSONObject()
try {
json.put("iob", iob)
json.put("basaliob", basaliob)
json.put("bolussnooze", bolussnooze)
json.put("activity", activity)
json.put("lastBolusTime", lastBolusTime)
json.put("time", DateUtil.toISOString(Date(time)))
/*
This is requested by SMB determine_basal but by based on Scott's info
it's MDT specific safety check only
It's causing rounding issues in determine_basal
JSONObject lastTemp = new JSONObject();
lastTemp.put("date", lastTempDate);
lastTemp.put("rate", lastTempRate);
lastTemp.put("duration", lastTempDuration);
json.put("lastTemp", lastTemp);
*/
if (iobWithZeroTemp != null) {
val iwzt = iobWithZeroTemp!!.determineBasalJson()
json.put("iobWithZeroTemp", iwzt)
}
} catch (ignored: JSONException) {
}
return json
}
// DataPoint interface
private var color = 0
override fun getX(): Double {
return time.toDouble()
}
override fun getY(): Double {
return iob
}
override fun setY(y: Double) {}
override fun getLabel(): String {
return ""
}
override fun getDuration(): Long {
return 0
}
override fun getShape(): PointsWithLabelGraphSeries.Shape {
return PointsWithLabelGraphSeries.Shape.IOBPREDICTION
}
override fun getSize(): Float {
return 0.5f
}
override fun getColor(): Int {
return color
}
fun setColor(color: Int): IobTotal {
this.color = color
return this
}
companion object {
fun combine(bolusIOB: IobTotal, basalIob: IobTotal): IobTotal {
val result = IobTotal(bolusIOB.time)
result.iob = bolusIOB.iob + basalIob.basaliob
result.activity = bolusIOB.activity + basalIob.activity
result.bolussnooze = bolusIOB.bolussnooze
result.basaliob = bolusIOB.basaliob + basalIob.basaliob
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin
result.lastBolusTime = bolusIOB.lastBolusTime
result.iobWithZeroTemp = basalIob.iobWithZeroTemp
return result
}
}
}

View file

@ -1,15 +0,0 @@
package info.nightscout.androidaps.data;
/**
* Created by mike on 04.01.2017.
*/
public class MealData {
public double boluses = 0d;
public double carbs = 0d;
public double mealCOB = 0.0d;
public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999;
public long lastBolusTime;
public long lastCarbTime = 0L;
public double usedMinCarbsImpact = 0d;
}

View file

@ -0,0 +1,13 @@
package info.nightscout.androidaps.data
class MealData {
var boluses = 0.0
var carbs = 0.0
var mealCOB = 0.0
var slopeFromMaxDeviation = 0.0
var slopeFromMinDeviation = 999.0
var lastBolusTime: Long = 0
var lastCarbTime = 0L
var usedMinCarbsImpact = 0.0
}

View file

@ -1,39 +0,0 @@
package info.nightscout.androidaps.data;
import androidx.annotation.Nullable;
import info.nightscout.androidaps.interfaces.Interval;
/**
* Created by adrian on 15/07/17.
*/
public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
public NonOverlappingIntervals() {
super();
}
public NonOverlappingIntervals (Intervals<T> other) {
rawData = other.rawData.clone();
}
public synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index);
long startOfNewer = rawData.valueAt(index + 1).start();
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer);
}
}
}
@Nullable
public synchronized T getValueByInterval(long time) {
int index = binarySearch(time);
if (index >= 0) return rawData.valueAt(index);
return null;
}
}

View file

@ -0,0 +1,26 @@
package info.nightscout.androidaps.data
import info.nightscout.androidaps.interfaces.Interval
class NonOverlappingIntervals<T : Interval> : Intervals<T> {
constructor() : super()
constructor(other: Intervals<T>) {
rawData = other.rawData.clone()
}
@Synchronized public override fun merge() {
for (index in 0 until rawData.size() - 1) {
val i: T = rawData.valueAt(index)
val startOfNewer = rawData.valueAt(index + 1).start()
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer)
}
}
}
@Synchronized override fun getValueByInterval(time: Long): T? {
val index = binarySearch(time)
return if (index >= 0) rawData.valueAt(index) else null
}
}

View file

@ -1,51 +0,0 @@
package info.nightscout.androidaps.data;
import androidx.annotation.Nullable;
import info.nightscout.androidaps.interfaces.Interval;
/**
* Created by adrian on 15/07/17.
*/
public class OverlappingIntervals<T extends Interval> extends Intervals<T> {
public OverlappingIntervals() {
super();
}
public OverlappingIntervals(Intervals<T> other) {
rawData = other.rawData.clone();
}
protected synchronized void merge() {
boolean needToCut = false;
long cutTime = 0;
for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest
Interval cur = rawData.valueAt(index);
if (cur.isEndingEvent()) {
needToCut = true;
cutTime = cur.start();
} else {
//event that is no EndingEvent might need to be stopped by an ending event
if (needToCut && cur.end() > cutTime) {
cur.cutEndTo(cutTime);
}
}
}
}
@Nullable
public synchronized T getValueByInterval(long time) {
for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest
T cur = rawData.valueAt(index);
if (cur.match(time)) {
return cur;
}
}
return null;
}
}

View file

@ -0,0 +1,38 @@
package info.nightscout.androidaps.data
import info.nightscout.androidaps.interfaces.Interval
class OverlappingIntervals<T : Interval> : Intervals<T> {
constructor() : super()
constructor(other: Intervals<T>) {
rawData = other.rawData.clone()
}
@Synchronized override fun merge() {
var needToCut = false
var cutTime: Long = 0
for (index in rawData.size() - 1 downTo 0) { //begin with newest
val cur: Interval = rawData.valueAt(index)
if (cur.isEndingEvent) {
needToCut = true
cutTime = cur.start()
} else {
//event that is no EndingEvent might need to be stopped by an ending event
if (needToCut && cur.end() > cutTime) {
cur.cutEndTo(cutTime)
}
}
}
}
@Synchronized override fun getValueByInterval(time: Long): T? {
for (index in rawData.size() - 1 downTo 0) { //begin with newest
val cur = rawData.valueAt(index)
if (cur!!.match(time)) {
return cur
}
}
return null
}
}

View file

@ -245,7 +245,7 @@ public class Profile {
if (isValid) { if (isValid) {
// Check for hours alignment // Check for hours alignment
PumpInterface pump = activePlugin.getActivePump(); PumpInterface pump = activePlugin.getActivePump();
if (!pump.getPumpDescription().is30minBasalRatesCapable) { if (!pump.getPumpDescription().is30minBasalRatesCapable()) {
for (int index = 0; index < basal_v.size(); index++) { for (int index = 0; index < basal_v.size(); index++) {
long secondsFromMidnight = basal_v.keyAt(index); long secondsFromMidnight = basal_v.keyAt(index);
if (notify && secondsFromMidnight % 3600 != 0) { if (notify && secondsFromMidnight % 3600 != 0) {
@ -260,12 +260,12 @@ public class Profile {
// Check for minimal basal value // Check for minimal basal value
PumpDescription description = pump.getPumpDescription(); PumpDescription description = pump.getPumpDescription();
for (int i = 0; i < basal_v.size(); i++) { for (int i = 0; i < basal_v.size(); i++) {
if (basal_v.valueAt(i) < description.basalMinimumRate) { if (basal_v.valueAt(i) < description.getBasalMinimumRate()) {
basal_v.setValueAt(i, description.basalMinimumRate); basal_v.setValueAt(i, description.getBasalMinimumRate());
if (notify) if (notify)
sendBelowMinimumNotification(from); sendBelowMinimumNotification(from);
} else if (basal_v.valueAt(i) > description.basalMaximumRate) { } else if (basal_v.valueAt(i) > description.getBasalMaximumRate()) {
basal_v.setValueAt(i, description.basalMaximumRate); basal_v.setValueAt(i, description.getBasalMaximumRate());
if (notify) if (notify)
sendAboveMaximumNotification(from); sendAboveMaximumNotification(from);
} }
@ -666,14 +666,14 @@ public class Profile {
} }
public static String toUnitsString(double valueInMgdl, double valueInMmol, String units) { public static String toUnitsString(double valueInMgdl, double valueInMmol, String units) {
if (units.equals(Constants.MGDL)) return DecimalFormatter.to0Decimal(valueInMgdl); if (units.equals(Constants.MGDL)) return DecimalFormatter.INSTANCE.to0Decimal(valueInMgdl);
else return DecimalFormatter.to1Decimal(valueInMmol); else return DecimalFormatter.INSTANCE.to1Decimal(valueInMmol);
} }
public static String toSignedUnitsString(double valueInMgdl, double valueInMmol, String units) { public static String toSignedUnitsString(double valueInMgdl, double valueInMmol, String units) {
if (units.equals(Constants.MGDL)) if (units.equals(Constants.MGDL))
return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.to0Decimal(valueInMgdl); return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.INSTANCE.to0Decimal(valueInMgdl);
else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.to1Decimal(valueInMmol); else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.INSTANCE.to1Decimal(valueInMmol);
} }
public static double toCurrentUnits(ProfileFunction profileFunction, double anyBg) { public static double toCurrentUnits(ProfileFunction profileFunction, double anyBg) {

View file

@ -1,132 +0,0 @@
package info.nightscout.androidaps.data;
import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.interfaces.Interval;
/**
* Created by mike on 09.05.2017.
*/
// Zero duration means profile is valid until is chaged
// When no interval match the lastest record without duration is used
public class ProfileIntervals<T extends Interval> {
private LongSparseArray<T> rawData; // oldest at index 0
public ProfileIntervals() {
rawData = new LongSparseArray<>();
}
public ProfileIntervals(ProfileIntervals<T> other) {
rawData = other.rawData.clone();
}
public synchronized ProfileIntervals<T> reset() {
rawData = new LongSparseArray<>();
return this;
}
public synchronized void add(T newInterval) {
if (newInterval.isValid()) {
rawData.put(newInterval.start(), newInterval);
merge();
}
}
public synchronized void add(List<T> list) {
for (T interval : list) {
if (interval.isValid())
rawData.put(interval.start(), interval);
}
merge();
}
private synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index);
long startOfNewer = rawData.valueAt(index + 1).start();
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer);
}
}
}
@Nullable
public synchronized Interval getValueToTime(long time) {
int index = binarySearch(time);
if (index >= 0) return rawData.valueAt(index);
// if we request data older than first record, use oldest with zero duration instead
for (index = 0; index < rawData.size(); index++) {
if (rawData.valueAt(index).durationInMsec() == 0) {
//log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
return rawData.valueAt(index);
}
}
return null;
}
public synchronized List<T> getList() {
List<T> list = new ArrayList<>();
for (int i = 0; i < rawData.size(); i++)
list.add(rawData.valueAt(i));
return list;
}
public synchronized List<T> getReversedList() {
List<T> list = new ArrayList<>();
for (int i = rawData.size() - 1; i >= 0; i--)
list.add(rawData.valueAt(i));
return list;
}
private synchronized int binarySearch(long value) {
if (rawData.size() == 0)
return -1;
int lo = 0;
int hi = rawData.size() - 1;
while (lo <= hi) {
final int mid = (lo + hi) >>> 1;
final Interval midVal = rawData.valueAt(mid);
if (midVal.match(value)) {
return mid; // value found
} else if (midVal.before(value)) {
lo = mid + 1;
} else if (midVal.after(value)) {
hi = mid - 1;
}
}
// not found, try nearest older with duration 0
lo = lo - 1;
while (lo >= 0 && lo < rawData.size()) {
if (rawData.valueAt(lo).isEndingEvent())
return lo;
lo--;
}
return -1; // value not present
}
public synchronized int size() {
return rawData.size();
}
public synchronized T get(int index) {
return rawData.valueAt(index);
}
public synchronized T getReversed(int index) {
return rawData.valueAt(size() - 1 - index);
}
@Override
public String toString() {
return rawData.toString();
}
}

View file

@ -0,0 +1,115 @@
package info.nightscout.androidaps.data
import androidx.collection.LongSparseArray
import info.nightscout.androidaps.interfaces.Interval
import java.util.*
// Zero duration means profile is valid until is changed
// When no interval match the latest record without duration is used
class ProfileIntervals<T : Interval> {
private var rawData: LongSparseArray<T> // oldest at index 0
constructor() {
rawData = LongSparseArray()
}
constructor(other: ProfileIntervals<T>) {
rawData = other.rawData.clone()
}
@Synchronized fun reset(): ProfileIntervals<T> {
rawData = LongSparseArray()
return this
}
@Synchronized fun add(newInterval: T) {
if (newInterval.isValid) {
rawData.put(newInterval.start(), newInterval)
merge()
}
}
@Synchronized fun add(list: List<T>) {
for (interval in list) {
if (interval.isValid) rawData.put(interval.start(), interval)
}
merge()
}
@Synchronized private fun merge() {
for (index in 0 until rawData.size() - 1) {
val i: T = rawData.valueAt(index)
val startOfNewer = rawData.valueAt(index + 1)!!.start()
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer)
}
}
}
@Synchronized fun getValueToTime(time: Long): Interval? {
var index = binarySearch(time)
if (index >= 0) return rawData.valueAt(index)
// if we request data older than first record, use oldest with zero duration instead
index = 0
while (index < rawData.size()) {
if (rawData.valueAt(index)!!.durationInMsec() == 0L) {
//log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
return rawData.valueAt(index)
}
index++
}
return null
}
@get:Synchronized val list: List<T>
get() {
val list: MutableList<T> = ArrayList()
for (i in 0 until rawData.size()) list.add(rawData.valueAt(i))
return list
}
@get:Synchronized val reversedList: List<T>
get() {
val list: MutableList<T> = ArrayList()
for (i in rawData.size() - 1 downTo 0) list.add(rawData.valueAt(i))
return list
}
@Synchronized private fun binarySearch(value: Long): Int {
if (rawData.size() == 0) return -1
var lo = 0
var hi = rawData.size() - 1
while (lo <= hi) {
val mid = lo + hi ushr 1
val midVal: Interval = rawData.valueAt(mid)
when {
midVal.match(value) -> return mid // value found
midVal.before(value) -> lo = mid + 1
midVal.after(value) -> hi = mid - 1
}
}
// not found, try nearest older with duration 0
lo -= 1
while (lo >= 0 && lo < rawData.size()) {
if (rawData.valueAt(lo)!!.isEndingEvent) return lo
lo--
}
return -1 // value not present
}
@Synchronized fun size(): Int {
return rawData.size()
}
@Synchronized operator fun get(index: Int): T? {
return rawData.valueAt(index)
}
@Synchronized fun getReversed(index: Int): T {
return rawData.valueAt(size() - 1 - index)
}
override fun toString(): String {
return rawData.toString()
}
}

View file

@ -1,201 +0,0 @@
package info.nightscout.androidaps.data;
import org.json.JSONException;
import org.json.JSONObject;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.core.R;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
public class PumpEnactResult {
@Inject public AAPSLogger aapsLogger;
@Inject public ResourceHelper resourceHelper;
public boolean success = false; // request was processed successfully (but possible no change was needed)
public boolean enacted = false; // request was processed successfully and change has been made
public String comment = "";
// Result of basal change
public int duration = -1; // duration set [minutes]
public double absolute = -1d; // absolute rate [U/h] , isPercent = false
public int percent = -1; // percent of current basal [%] (100% = current basal), isPercent = true
public boolean isPercent = false; // if true percent is used, otherwise absolute
public boolean isTempCancel = false; // if true we are caceling temp basal
// Result of treatment delivery
public double bolusDelivered = 0d; // real value of delivered insulin
public double carbsDelivered = 0d; // real value of delivered carbs
public boolean queued = false;
public PumpEnactResult(HasAndroidInjector injector) {
injector.androidInjector().inject(this);
}
public PumpEnactResult success(boolean success) {
this.success = success;
return this;
}
public PumpEnactResult enacted(boolean enacted) {
this.enacted = enacted;
return this;
}
public PumpEnactResult comment(String comment) {
this.comment = comment;
return this;
}
public PumpEnactResult comment(int comment) {
this.comment = resourceHelper.gs(comment);
return this;
}
public PumpEnactResult duration(int duration) {
this.duration = duration;
return this;
}
public PumpEnactResult absolute(double absolute) {
this.absolute = absolute;
return this;
}
public PumpEnactResult percent(int percent) {
this.percent = percent;
return this;
}
public PumpEnactResult isPercent(boolean isPercent) {
this.isPercent = isPercent;
return this;
}
public PumpEnactResult isTempCancel(boolean isTempCancel) {
this.isTempCancel = isTempCancel;
return this;
}
public PumpEnactResult bolusDelivered(double bolusDelivered) {
this.bolusDelivered = bolusDelivered;
return this;
}
public PumpEnactResult carbsDelivered(double carbsDelivered) {
this.carbsDelivered = carbsDelivered;
return this;
}
public PumpEnactResult queued(boolean queued) {
this.queued = queued;
return this;
}
public String log() {
return "Success: " + success +
" Enacted: " + enacted +
" Comment: " + comment +
" Duration: " + duration +
" Absolute: " + absolute +
" Percent: " + percent +
" IsPercent: " + isPercent +
" IsTempCancel: " + isTempCancel +
" bolusDelivered: " + bolusDelivered +
" carbsDelivered: " + carbsDelivered +
" Queued: " + queued;
}
public String toString() {
String ret = resourceHelper.gs(R.string.success) + ": " + success;
if (enacted) {
if (bolusDelivered > 0) {
ret += "\n" + resourceHelper.gs(R.string.enacted) + ": " + enacted;
ret += "\n" + resourceHelper.gs(R.string.comment) + ": " + comment;
ret += "\n" + resourceHelper.gs(R.string.configbuilder_insulin)
+ ": " + bolusDelivered + " " + resourceHelper.gs(R.string.insulin_unit_shortname);
} else if (isTempCancel) {
ret += "\n" + resourceHelper.gs(R.string.enacted) + ": " + enacted;
if (!comment.isEmpty())
ret += "\n" + resourceHelper.gs(R.string.comment) + ": " + comment;
ret += "\n" + resourceHelper.gs(R.string.canceltemp);
} else if (isPercent) {
ret += "\n" + resourceHelper.gs(R.string.enacted) + ": " + enacted;
if (!comment.isEmpty())
ret += "\n" + resourceHelper.gs(R.string.comment) + ": " + comment;
ret += "\n" + resourceHelper.gs(R.string.duration) + ": " + duration + " min";
ret += "\n" + resourceHelper.gs(R.string.percent) + ": " + percent + "%";
} else {
ret += "\n" + resourceHelper.gs(R.string.enacted) + ": " + enacted;
if (!comment.isEmpty())
ret += "\n" + resourceHelper.gs(R.string.comment) + ": " + comment;
ret += "\n" + resourceHelper.gs(R.string.duration) + ": " + duration + " min";
ret += "\n" + resourceHelper.gs(R.string.absolute) + ": " + absolute + " U/h";
}
} else {
ret += "\n" + resourceHelper.gs(R.string.comment) + ": " + comment;
}
return ret;
}
public String toHtml() {
String ret = "<b>" + resourceHelper.gs(R.string.success) + "</b>: " + success;
if (queued) {
ret = resourceHelper.gs(R.string.waitingforpumpresult);
} else if (enacted) {
if (bolusDelivered > 0) {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted;
if (!comment.isEmpty())
ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment;
ret += "<br><b>" + resourceHelper.gs(R.string.smb_shortname) + "</b>: " + bolusDelivered + " " + resourceHelper.gs(R.string.insulin_unit_shortname);
} else if (isTempCancel) {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted;
ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment +
"<br>" + resourceHelper.gs(R.string.canceltemp);
} else if (isPercent && percent != -1) {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted;
if (!comment.isEmpty())
ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment;
ret += "<br><b>" + resourceHelper.gs(R.string.duration) + "</b>: " + duration + " min";
ret += "<br><b>" + resourceHelper.gs(R.string.percent) + "</b>: " + percent + "%";
} else if (absolute != -1) {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted;
if (!comment.isEmpty())
ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment;
ret += "<br><b>" + resourceHelper.gs(R.string.duration) + "</b>: " + duration + " min";
ret += "<br><b>" + resourceHelper.gs(R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h";
}
} else {
if (!comment.isEmpty())
ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment;
}
return ret;
}
public JSONObject json(Profile profile) {
JSONObject result = new JSONObject();
try {
if (bolusDelivered > 0) {
result.put("smb", bolusDelivered);
} else if (isTempCancel) {
result.put("rate", 0);
result.put("duration", 0);
} else if (isPercent) {
// Nightscout is expecting absolute value
Double abs = Round.roundTo(profile.getBasal() * percent / 100, 0.01);
result.put("rate", abs);
result.put("duration", duration);
} else {
result.put("rate", absolute);
result.put("duration", duration);
}
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
return result;
}
}

View file

@ -0,0 +1,165 @@
package info.nightscout.androidaps.data
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONObject
import javax.inject.Inject
class PumpEnactResult(injector: HasAndroidInjector) {
@Inject lateinit var resourceHelper: ResourceHelper
init {
injector.androidInjector().inject(this)
}
var success = false // request was processed successfully (but possible no change was needed)
var enacted = false // request was processed successfully and change has been made
var comment = ""
// Result of basal change
var duration = -1 // duration set [minutes]
var absolute = -1.0 // absolute rate [U/h] , isPercent = false
var percent = -1 // percent of current basal [%] (100% = current basal), isPercent = true
var isPercent = false // if true percent is used, otherwise absolute
var isTempCancel = false // if true we are canceling temp basal
// Result of treatment delivery
var bolusDelivered = 0.0 // real value of delivered insulin
var carbsDelivered = 0.0 // real value of delivered carbs
var queued = false
fun success(success: Boolean): PumpEnactResult {
this.success = success
return this
}
fun enacted(enacted: Boolean): PumpEnactResult = this.also { it.enacted = enacted }
fun comment(comment: String): PumpEnactResult = this.also { it.comment = comment }
fun comment(comment: Int): PumpEnactResult = this.also { it.comment = resourceHelper.gs(comment) }
fun duration(duration: Int): PumpEnactResult = this.also { it.duration = duration }
fun absolute(absolute: Double): PumpEnactResult = this.also { it.absolute = absolute }
fun percent(percent: Int): PumpEnactResult = this.also { it.percent = percent }
fun isPercent(isPercent: Boolean): PumpEnactResult = this.also { it.isPercent = isPercent }
fun isTempCancel(isTempCancel: Boolean): PumpEnactResult = this.also { it.isTempCancel = isTempCancel }
fun bolusDelivered(bolusDelivered: Double): PumpEnactResult = this.also { it.bolusDelivered = bolusDelivered }
fun carbsDelivered(carbsDelivered: Double): PumpEnactResult = this.also { it.carbsDelivered = carbsDelivered }
fun queued(queued: Boolean): PumpEnactResult = this.also { it.queued = queued }
fun log(): String {
return "Success: " + success +
" Enacted: " + enacted +
" Comment: " + comment +
" Duration: " + duration +
" Absolute: " + absolute +
" Percent: " + percent +
" IsPercent: " + isPercent +
" IsTempCancel: " + isTempCancel +
" bolusDelivered: " + bolusDelivered +
" carbsDelivered: " + carbsDelivered +
" Queued: " + queued
}
override fun toString(): String {
var ret = resourceHelper.gs(R.string.success) + ": " + success
if (enacted) {
when {
bolusDelivered > 0 -> {
ret += "\n${resourceHelper.gs(R.string.enacted)}: $enacted"
ret += "\n${resourceHelper.gs(R.string.comment)}: $comment"
ret += "\n${resourceHelper.gs(R.string.configbuilder_insulin)}: $bolusDelivered ${resourceHelper.gs(R.string.insulin_unit_shortname)}"
}
isTempCancel -> {
ret += "\n${resourceHelper.gs(R.string.enacted)}: $enacted"
if (comment.isNotEmpty()) ret += "\n${resourceHelper.gs(R.string.comment)}: $comment"
ret += "\n${resourceHelper.gs(R.string.canceltemp)}"
}
isPercent -> {
ret += "\n${resourceHelper.gs(R.string.enacted)}: $enacted"
if (comment.isNotEmpty()) ret += "\n${resourceHelper.gs(R.string.comment)}: $comment"
ret += "\n${resourceHelper.gs(R.string.duration)}: $duration min"
ret += "\n${resourceHelper.gs(R.string.percent)}: $percent%"
}
else -> {
ret += "\n${resourceHelper.gs(R.string.enacted)}: $enacted"
if (comment.isNotEmpty()) ret += "\n${resourceHelper.gs(R.string.comment)}: $comment"
ret += "\n${resourceHelper.gs(R.string.duration)}: $duration min"
ret += "\n${resourceHelper.gs(R.string.absolute)}: $absolute U/h"
}
}
} else {
ret += "\n${resourceHelper.gs(R.string.comment)}: $comment"
}
return ret
}
fun toHtml(): String {
var ret = "<b>" + resourceHelper.gs(R.string.success) + "</b>: " + success
if (queued) {
ret = resourceHelper.gs(R.string.waitingforpumpresult)
} else if (enacted) {
when {
bolusDelivered > 0 -> {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted
if (comment.isNotEmpty()) ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment
ret += "<br><b>" + resourceHelper.gs(R.string.smb_shortname) + "</b>: " + bolusDelivered + " " + resourceHelper.gs(R.string.insulin_unit_shortname)
}
isTempCancel -> {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted
ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment +
"<br>" + resourceHelper.gs(R.string.canceltemp)
}
isPercent && percent != -1 -> {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted
if (comment.isNotEmpty()) ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment
ret += "<br><b>" + resourceHelper.gs(R.string.duration) + "</b>: " + duration + " min"
ret += "<br><b>" + resourceHelper.gs(R.string.percent) + "</b>: " + percent + "%"
}
absolute != -1.0 -> {
ret += "<br><b>" + resourceHelper.gs(R.string.enacted) + "</b>: " + enacted
if (comment.isNotEmpty()) ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment
ret += "<br><b>" + resourceHelper.gs(R.string.duration) + "</b>: " + duration + " min"
ret += "<br><b>" + resourceHelper.gs(R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h"
}
}
} else {
if (comment.isNotEmpty()) ret += "<br><b>" + resourceHelper.gs(R.string.comment) + "</b>: " + comment
}
return ret
}
fun json(profile: Profile): JSONObject {
val result = JSONObject()
when {
bolusDelivered > 0 -> {
result.put("smb", bolusDelivered)
}
isTempCancel -> {
result.put("rate", 0)
result.put("duration", 0)
}
isPercent -> {
// Nightscout is expecting absolute value
val abs = Round.roundTo(profile.basal * percent / 100, 0.01)
result.put("rate", abs)
result.put("duration", duration)
}
else -> {
result.put("rate", absolute)
result.put("duration", duration)
}
}
return result
}
}

View file

@ -254,8 +254,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.iob += aIOB.iobContrib; result.iob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.extendedBolusInsulin += tempBolusPart.insulin; result.extendedBolusInsulin += tempBolusPart.insulin;
} }
} }
@ -305,8 +305,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.iob += aIOB.iobContrib; result.iob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.extendedBolusInsulin += tempBolusPart.insulin; result.extendedBolusInsulin += tempBolusPart.insulin;
} }
} }
@ -330,23 +330,23 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
} }
public String toString() { public String toString() {
return "E " + DecimalFormatter.to2Decimal(absoluteRate()) + "U/h @" + return "E " + DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + "U/h @" +
dateUtil.timeString(date) + dateUtil.timeString(date) +
" " + getRealDuration() + "/" + durationInMinutes + "min"; " " + getRealDuration() + "/" + durationInMinutes + "min";
} }
public String toStringShort() { public String toStringShort() {
return "E " + DecimalFormatter.to2Decimal(absoluteRate()) + "U/h "; return "E " + DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + "U/h ";
} }
public String toStringMedium() { public String toStringMedium() {
return DecimalFormatter.to2Decimal(absoluteRate()) + "U/h " return DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + "U/h "
+ getRealDuration() + "/" + durationInMinutes + "'"; + getRealDuration() + "/" + durationInMinutes + "'";
} }
public String toStringTotal() { public String toStringTotal() {
return DecimalFormatter.to2Decimal(insulin) + "U ( " + return DecimalFormatter.INSTANCE.to2Decimal(insulin) + "U ( " +
DecimalFormatter.to2Decimal(absoluteRate()) + " U/h )"; DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + " U/h )";
} }
// -------- DataPointWithLabelInterface -------- // -------- DataPointWithLabelInterface --------

View file

@ -130,7 +130,7 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
public String getCustomizedName() { public String getCustomizedName() {
String name = profileName; String name = profileName;
if (Constants.LOCAL_PROFILE.equals(name)) { if (Constants.LOCAL_PROFILE.equals(name)) {
name = DecimalFormatter.to2Decimal(getProfileObject().percentageBasalSum()) + "U "; name = DecimalFormatter.INSTANCE.to2Decimal(getProfileObject().percentageBasalSum()) + "U ";
} }
if (isCPP) { if (isCPP) {
name += "(" + percentage + "%"; name += "(" + percentage + "%";

View file

@ -285,8 +285,8 @@ public class TemporaryBasal implements Interval, DbObjectBase {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.basaliob += aIOB.iobContrib; result.basaliob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.netbasalinsulin += tempBolusPart.insulin; result.netbasalinsulin += tempBolusPart.insulin;
if (tempBolusPart.insulin > 0) { if (tempBolusPart.insulin > 0) {
result.hightempinsulin += tempBolusPart.insulin; result.hightempinsulin += tempBolusPart.insulin;
@ -352,8 +352,8 @@ public class TemporaryBasal implements Interval, DbObjectBase {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.basaliob += aIOB.iobContrib; result.basaliob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.netbasalinsulin += tempBolusPart.insulin; result.netbasalinsulin += tempBolusPart.insulin;
if (tempBolusPart.insulin > 0) { if (tempBolusPart.insulin > 0) {
result.hightempinsulin += tempBolusPart.insulin; result.hightempinsulin += tempBolusPart.insulin;
@ -431,11 +431,11 @@ public class TemporaryBasal implements Interval, DbObjectBase {
return "null"; return "null";
Double currentBasalRate = profile.getBasal(); Double currentBasalRate = profile.getBasal();
double rate = currentBasalRate + netExtendedRate; double rate = currentBasalRate + netExtendedRate;
return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h (" + DecimalFormatter.to2Decimal(netExtendedRate) + "E) @" + return getCalcuatedPercentageIfNeeded() + DecimalFormatter.INSTANCE.to2Decimal(rate) + "U/h (" + DecimalFormatter.INSTANCE.to2Decimal(netExtendedRate) + "E) @" +
dateUtil.timeString(date) + dateUtil.timeString(date) +
" " + getRealDuration() + "/" + durationInMinutes + "'"; " " + getRealDuration() + "/" + durationInMinutes + "'";
} else if (isAbsolute) { } else if (isAbsolute) {
return DecimalFormatter.to2Decimal(absoluteRate) + "U/h @" + return DecimalFormatter.INSTANCE.to2Decimal(absoluteRate) + "U/h @" +
dateUtil.timeString(date) + dateUtil.timeString(date) +
" " + getRealDuration() + "/" + durationInMinutes + "'"; " " + getRealDuration() + "/" + durationInMinutes + "'";
} else { // percent } else { // percent
@ -468,7 +468,7 @@ public class TemporaryBasal implements Interval, DbObjectBase {
} }
} }
} }
return DecimalFormatter.to2Decimal(rate) + "U/h"; return DecimalFormatter.INSTANCE.to2Decimal(rate) + "U/h";
} else { // percent } else { // percent
return percentRate + "%"; return percentRate + "%";
} }
@ -515,7 +515,7 @@ public class TemporaryBasal implements Interval, DbObjectBase {
} else { } else {
rate = absoluteRate; rate = absoluteRate;
} }
return DecimalFormatter.to2Decimal(rate) + "U/h"; return DecimalFormatter.INSTANCE.to2Decimal(rate) + "U/h";
} else { // percent } else { // percent
return percentRate + "%"; return percentRate + "%";
} }

View file

@ -243,7 +243,7 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
@Override @Override
public String getLabel() { public String getLabel() {
String label = ""; String label = "";
if (insulin > 0) label += DecimalFormatter.toPumpSupportedBolus(insulin, activePlugin.getActivePump(), resourceHelper); if (insulin > 0) label += DecimalFormatter.INSTANCE.toPumpSupportedBolus(insulin, activePlugin.getActivePump(), resourceHelper);
if (carbs > 0) if (carbs > 0)
label += "~" + resourceHelper.gs(R.string.format_carbs, (int) carbs); label += "~" + resourceHelper.gs(R.string.format_carbs, (int) carbs);
return label; return label;

View file

@ -1,129 +0,0 @@
package info.nightscout.androidaps.interfaces;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
/**
* Created by mike on 19.03.2018.
*/
public class Constraint<T extends Comparable<T>> {
private T value;
private T originalValue;
private final List<String> reasons = new ArrayList<>();
private final List<String> mostLimiting = new ArrayList<>();
public Constraint(T value) {
this.value = value;
this.originalValue = value;
}
public T value() {
return value;
}
public T originalValue() {
return originalValue;
}
public Constraint<T> set(AAPSLogger aapsLogger, T value) {
this.value = value;
this.originalValue = value;
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value " + value);
return this;
}
public Constraint<T> set(AAPSLogger aapsLogger, T value, String reason, Object from) {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
addReason(reason, from);
addMostLimingReason(reason, from);
return this;
}
public Constraint<T> setIfDifferent(AAPSLogger aapsLogger, T value, String reason, Object from) {
if (!this.value.equals(value)) {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
addReason(reason, from);
addMostLimingReason(reason, from);
}
return this;
}
public Constraint<T> setIfSmaller(AAPSLogger aapsLogger, T value, String reason, Object from) {
if (value.compareTo(this.value) < 0) {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
mostLimiting.clear();
addMostLimingReason(reason, from);
}
if (value.compareTo(this.originalValue) < 0) {
addReason(reason, from);
}
return this;
}
public Constraint<T> setIfGreater(AAPSLogger aapsLogger, T value, String reason, Object from) {
if (value.compareTo(this.value) > 0) {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
mostLimiting.clear();
addMostLimingReason(reason, from);
}
if (value.compareTo(this.originalValue) > 0) {
addReason(reason, from);
}
return this;
}
private String translateFrom(Object from) {
return from.getClass().getSimpleName().replace("Plugin", "");
}
public void addReason(String reason, Object from) {
reasons.add(translateFrom(from) + ": " + reason);
}
private void addMostLimingReason(String reason, Object from) {
mostLimiting.add(translateFrom(from) + ": " + reason);
}
public String getReasons(AAPSLogger aapsLogger) {
StringBuilder sb = new StringBuilder();
int count = 0;
for (String r : reasons) {
if (count++ != 0) sb.append("\n");
sb.append(r);
}
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
return sb.toString();
}
public List<String> getReasonList() {
return reasons;
}
public String getMostLimitedReasons(AAPSLogger aapsLogger) {
StringBuilder sb = new StringBuilder();
int count = 0;
for (String r : mostLimiting) {
if (count++ != 0) sb.append("\n");
sb.append(r);
}
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
return sb.toString();
}
public List<String> getMostLimitedReasonList() {
return mostLimiting;
}
public void copyReasons(Constraint<?> another) {
reasons.addAll(another.getReasonList());
}
}

View file

@ -0,0 +1,116 @@
package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import java.util.*
class Constraint<T : Comparable<T>>(private var value: T) {
private var originalValue: T
private val reasons: MutableList<String> = ArrayList()
private val mostLimiting: MutableList<String> = ArrayList()
fun value(): T {
return value
}
fun originalValue(): T {
return originalValue
}
operator fun set(aapsLogger: AAPSLogger, value: T): Constraint<T> {
this.value = value
originalValue = value
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value $value")
return this
}
operator fun set(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
this.value = value
addReason(reason, from)
addMostLimingReason(reason, from)
return this
}
fun setIfDifferent(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
if (this.value != value) {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
this.value = value
addReason(reason, from)
addMostLimingReason(reason, from)
}
return this
}
fun setIfSmaller(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
if (value < this.value) {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
this.value = value
mostLimiting.clear()
addMostLimingReason(reason, from)
}
if (value < originalValue) {
addReason(reason, from)
}
return this
}
fun setIfGreater(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
if (value > this.value) {
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
this.value = value
mostLimiting.clear()
addMostLimingReason(reason, from)
}
if (value > originalValue) {
addReason(reason, from)
}
return this
}
private fun translateFrom(from: Any): String {
return from.javaClass.simpleName.replace("Plugin", "")
}
fun addReason(reason: String, from: Any) {
reasons.add(translateFrom(from) + ": " + reason)
}
private fun addMostLimingReason(reason: String, from: Any) {
mostLimiting.add(translateFrom(from) + ": " + reason)
}
fun getReasons(aapsLogger: AAPSLogger): String {
val sb = StringBuilder()
for ((count, r) in reasons.withIndex()) {
if (count != 0) sb.append("\n")
sb.append(r)
}
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
return sb.toString()
}
val reasonList: List<String>
get() = reasons
fun getMostLimitedReasons(aapsLogger: AAPSLogger): String {
val sb = StringBuilder()
for ((count, r) in mostLimiting.withIndex()) {
if (count != 0) sb.append("\n")
sb.append(r)
}
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
return sb.toString()
}
val mostLimitedReasonList: List<String>
get() = mostLimiting
fun copyReasons(another: Constraint<*>) {
reasons.addAll(another.reasonList)
}
init {
originalValue = value
}
}

View file

@ -1,28 +0,0 @@
package info.nightscout.androidaps.interfaces;
import dagger.android.HasAndroidInjector;
/**
* Created by mike on 21.05.2017.
*/
public interface Interval {
long durationInMsec();
long start();
// planned end time at time of creation
long originalEnd();
// end time after cut
long end();
void cutEndTo(long end);
boolean match(long time);
boolean before(long time);
boolean after(long time);
boolean isInProgress();
boolean isEndingEvent();
boolean isValid();
}

View file

@ -0,0 +1,20 @@
package info.nightscout.androidaps.interfaces
interface Interval {
fun durationInMsec(): Long
fun start(): Long
// planned end time at time of creation
fun originalEnd(): Long
// end time after cut
fun end(): Long
fun cutEndTo(end: Long)
fun match(time: Long): Boolean
fun before(time: Long): Boolean
fun after(time: Long): Boolean
val isInProgress: Boolean
val isEndingEvent: Boolean
val isValid: Boolean
}

View file

@ -1,96 +0,0 @@
package info.nightscout.androidaps.interfaces;
public class PluginDescription {
PluginType mainType = PluginType.GENERAL;
String fragmentClass = null;
public boolean alwaysVisible = false;
public boolean neverVisible = false;
public boolean alwaysEnabled = false;
boolean showInList = true;
int pluginName = -1;
int shortName = -1;
int description = -1;
int preferencesId = -1;
public boolean enableByDefault = false;
public boolean visibleByDefault = false;
boolean defaultPlugin = false;
int pluginIcon = -1;
public PluginDescription mainType(PluginType mainType) {
this.mainType = mainType;
return this;
}
public PluginDescription fragmentClass(String fragmentClass) {
this.fragmentClass = fragmentClass;
return this;
}
public PluginDescription alwaysEnabled(boolean alwaysEnabled) {
this.alwaysEnabled = alwaysEnabled;
return this;
}
public PluginDescription alwaysVisible(boolean alwaysVisible) {
this.alwaysVisible = alwaysVisible;
return this;
}
public PluginDescription neverVisible(boolean neverVisible) {
this.neverVisible = neverVisible;
return this;
}
public PluginDescription showInList(boolean showInList) {
this.showInList = showInList;
return this;
}
public PluginDescription pluginIcon(int pluginIcon) {
this.pluginIcon = pluginIcon;
return this;
}
public PluginDescription pluginName(int pluginName) {
this.pluginName = pluginName;
return this;
}
public PluginDescription shortName(int shortName) {
this.shortName = shortName;
return this;
}
public PluginDescription preferencesId(int preferencesId) {
this.preferencesId = preferencesId;
return this;
}
public PluginDescription enableByDefault(boolean enableByDefault) {
this.enableByDefault = enableByDefault;
return this;
}
public PluginDescription visibleByDefault(boolean visibleByDefault) {
this.visibleByDefault = visibleByDefault;
return this;
}
public PluginDescription description(int description) {
this.description = description;
return this;
}
public PluginDescription setDefault() {
defaultPlugin = true;
return this;
}
public String getFragmentClass() {
return fragmentClass;
}
public PluginType getType() {
return mainType;
}
}

View file

@ -0,0 +1,34 @@
package info.nightscout.androidaps.interfaces
open class PluginDescription {
var mainType = PluginType.GENERAL
var fragmentClass: String? = null
var alwaysVisible = false
var neverVisible = false
var alwaysEnabled = false
var showInList = true
var pluginName = -1
var shortName = -1
var description = -1
var preferencesId = -1
var enableByDefault = false
var visibleByDefault = false
var defaultPlugin = false
var pluginIcon = -1
fun mainType(mainType: PluginType): PluginDescription = this.also { it.mainType = mainType }
fun fragmentClass(fragmentClass: String?): PluginDescription = this.also { it.fragmentClass = fragmentClass }
fun alwaysEnabled(alwaysEnabled: Boolean): PluginDescription = this.also { it.alwaysEnabled = alwaysEnabled }
fun alwaysVisible(alwaysVisible: Boolean): PluginDescription = this.also { it.alwaysVisible = alwaysVisible }
fun neverVisible(neverVisible: Boolean): PluginDescription = this.also { it.neverVisible = neverVisible }
fun showInList(showInList: Boolean): PluginDescription = this.also { it.showInList = showInList }
fun pluginIcon(pluginIcon: Int): PluginDescription = this.also { it.pluginIcon = pluginIcon }
fun pluginName(pluginName: Int): PluginDescription = this.also { it.pluginName = pluginName }
fun shortName(shortName: Int): PluginDescription = this.also { it.shortName = shortName }
fun preferencesId(preferencesId: Int): PluginDescription = this.also { it.preferencesId = preferencesId }
fun enableByDefault(enableByDefault: Boolean): PluginDescription = this.also { it.enableByDefault = enableByDefault }
fun visibleByDefault(visibleByDefault: Boolean): PluginDescription = this.also { it.visibleByDefault = visibleByDefault }
fun description(description: Int): PluginDescription = this.also { it.description = description }
fun setDefault(): PluginDescription = this.also { it.defaultPlugin = true }
}

View file

@ -1,14 +0,0 @@
package info.nightscout.androidaps.interfaces;
public enum PluginType {
GENERAL,
TREATMENT,
SENSITIVITY,
PROFILE,
APS,
PUMP,
CONSTRAINTS,
LOOP,
BGSOURCE,
INSULIN
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.interfaces
enum class PluginType {
GENERAL, TREATMENT, SENSITIVITY, PROFILE, APS, PUMP, CONSTRAINTS, LOOP, BGSOURCE, INSULIN
}

View file

@ -1,152 +0,0 @@
package info.nightscout.androidaps.interfaces;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpCapability;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpTempBasalType;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
/**
* Created by mike on 08.12.2016.
*/
public class PumpDescription {
public PumpType pumpType = PumpType.GenericAAPS;
public PumpDescription() {
resetSettings();
}
public PumpDescription(PumpType pumpType) {
this();
setPumpDescription(pumpType);
}
public static final int NONE = 0;
public static final int PERCENT = 0x01;
public static final int ABSOLUTE = 0x02;
public boolean isBolusCapable;
public double bolusStep;
public boolean isExtendedBolusCapable;
public double extendedBolusStep;
public double extendedBolusDurationStep;
public double extendedBolusMaxDuration;
public boolean isTempBasalCapable;
public int tempBasalStyle;
public int maxTempPercent;
public int tempPercentStep;
public double maxTempAbsolute;
public double tempAbsoluteStep;
public int tempDurationStep;
public boolean tempDurationStep15mAllowed;
public boolean tempDurationStep30mAllowed;
public int tempMaxDuration;
public boolean isSetBasalProfileCapable;
public double basalStep;
public double basalMinimumRate;
public double basalMaximumRate;
public boolean isRefillingCapable;
public boolean isBatteryReplaceable;
public boolean storesCarbInfo;
public boolean is30minBasalRatesCapable;
public boolean supportsTDDs;
public boolean needsManualTDDLoad;
public boolean hasCustomUnreachableAlertCheck;
public void resetSettings() {
isBolusCapable = true;
bolusStep = 0.1d;
isExtendedBolusCapable = true;
extendedBolusStep = 0.1d;
extendedBolusDurationStep = 30;
extendedBolusMaxDuration = 12 * 60;
isTempBasalCapable = true;
tempBasalStyle = PERCENT;
maxTempPercent = 200;
tempPercentStep = 10;
maxTempAbsolute = 10;
tempAbsoluteStep = 0.05d;
tempDurationStep = 60;
tempMaxDuration = 12 * 60;
tempDurationStep15mAllowed = false;
tempDurationStep30mAllowed = false;
isSetBasalProfileCapable = true;
basalStep = 0.01d;
basalMinimumRate = 0.04d;
basalMaximumRate = 25d;
is30minBasalRatesCapable = false;
isRefillingCapable = true;
isBatteryReplaceable = true;
storesCarbInfo = true;
supportsTDDs = false;
needsManualTDDLoad = true;
hasCustomUnreachableAlertCheck = false;
}
public void setPumpDescription(PumpType pumpType) {
resetSettings();
this.pumpType = pumpType;
PumpCapability pumpCapability = pumpType.getPumpCapability();
isBolusCapable = pumpCapability.hasCapability(PumpCapability.Bolus);
bolusStep = pumpType.getBolusSize();
isExtendedBolusCapable = pumpCapability.hasCapability(PumpCapability.ExtendedBolus);
extendedBolusStep = pumpType.getExtendedBolusSettings().getStep();
extendedBolusDurationStep = pumpType.getExtendedBolusSettings().getDurationStep();
extendedBolusMaxDuration = pumpType.getExtendedBolusSettings().getMaxDuration();
isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TempBasal);
if (pumpType.getPumpTempBasalType() == PumpTempBasalType.Percent) {
tempBasalStyle = PERCENT;
maxTempPercent = pumpType.getTbrSettings().getMaxDose().intValue();
tempPercentStep = (int) pumpType.getTbrSettings().getStep();
} else {
tempBasalStyle = ABSOLUTE;
maxTempAbsolute = pumpType.getTbrSettings().getMaxDose();
tempAbsoluteStep = pumpType.getTbrSettings().getStep();
}
tempDurationStep = pumpType.getTbrSettings().getDurationStep();
tempMaxDuration = pumpType.getTbrSettings().getMaxDuration();
tempDurationStep15mAllowed = pumpType.getSpecialBasalDurations()
.hasCapability(PumpCapability.BasalRate_Duration15minAllowed);
tempDurationStep30mAllowed = pumpType.getSpecialBasalDurations()
.hasCapability(PumpCapability.BasalRate_Duration30minAllowed);
isSetBasalProfileCapable = pumpCapability.hasCapability(PumpCapability.BasalProfileSet);
basalStep = pumpType.getBaseBasalStep();
basalMinimumRate = pumpType.getBaseBasalMinValue();
isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill);
isBatteryReplaceable = pumpCapability.hasCapability(PumpCapability.ReplaceBattery);
storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo);
supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD);
needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad);
is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min);
hasCustomUnreachableAlertCheck = pumpType.getHasCustomUnreachableAlertCheck();
}
}

View file

@ -0,0 +1,120 @@
package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.plugins.pump.common.defs.PumpCapability
import info.nightscout.androidaps.plugins.pump.common.defs.PumpTempBasalType
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
class PumpDescription() {
constructor(pumpType: PumpType) : this() {
setPumpDescription(pumpType)
}
var pumpType = PumpType.GenericAAPS
var isBolusCapable = false
var bolusStep = 0.0
var isExtendedBolusCapable = false
var extendedBolusStep = 0.0
var extendedBolusDurationStep = 0.0
var extendedBolusMaxDuration = 0.0
var isTempBasalCapable = false
var tempBasalStyle = 0
var maxTempPercent = 0
var tempPercentStep = 0
var maxTempAbsolute = 0.0
var tempAbsoluteStep = 0.0
var tempDurationStep = 0
var tempDurationStep15mAllowed = false
var tempDurationStep30mAllowed = false
var tempMaxDuration = 0
var isSetBasalProfileCapable = false
var basalStep = 0.0
var basalMinimumRate = 0.0
var basalMaximumRate = 0.0
var isRefillingCapable = false
var isBatteryReplaceable = false
var storesCarbInfo = false
var is30minBasalRatesCapable = false
var supportsTDDs = false
var needsManualTDDLoad = false
var hasCustomUnreachableAlertCheck = false
fun resetSettings() {
isBolusCapable = true
bolusStep = 0.1
isExtendedBolusCapable = true
extendedBolusStep = 0.1
extendedBolusDurationStep = 30.0
extendedBolusMaxDuration = (12 * 60).toDouble()
isTempBasalCapable = true
tempBasalStyle = PERCENT
maxTempPercent = 200
tempPercentStep = 10
maxTempAbsolute = 10.0
tempAbsoluteStep = 0.05
tempDurationStep = 60
tempMaxDuration = 12 * 60
tempDurationStep15mAllowed = false
tempDurationStep30mAllowed = false
isSetBasalProfileCapable = true
basalStep = 0.01
basalMinimumRate = 0.04
basalMaximumRate = 25.0
is30minBasalRatesCapable = false
isRefillingCapable = true
isBatteryReplaceable = true
storesCarbInfo = true
supportsTDDs = false
needsManualTDDLoad = true
hasCustomUnreachableAlertCheck = false
}
fun setPumpDescription(pumpType: PumpType) {
resetSettings()
this.pumpType = pumpType
val pumpCapability = pumpType.pumpCapability
isBolusCapable = pumpCapability.hasCapability(PumpCapability.Bolus)
bolusStep = pumpType.bolusSize
isExtendedBolusCapable = pumpCapability.hasCapability(PumpCapability.ExtendedBolus)
extendedBolusStep = pumpType.extendedBolusSettings.step
extendedBolusDurationStep = pumpType.extendedBolusSettings.durationStep.toDouble()
extendedBolusMaxDuration = pumpType.extendedBolusSettings.maxDuration.toDouble()
isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TempBasal)
if (pumpType.pumpTempBasalType == PumpTempBasalType.Percent) {
tempBasalStyle = PERCENT
maxTempPercent = pumpType.tbrSettings.maxDose.toInt()
tempPercentStep = pumpType.tbrSettings.step.toInt()
} else {
tempBasalStyle = ABSOLUTE
maxTempAbsolute = pumpType.tbrSettings.maxDose
tempAbsoluteStep = pumpType.tbrSettings.step
}
tempDurationStep = pumpType.tbrSettings.durationStep
tempMaxDuration = pumpType.tbrSettings.maxDuration
tempDurationStep15mAllowed = pumpType.specialBasalDurations
.hasCapability(PumpCapability.BasalRate_Duration15minAllowed)
tempDurationStep30mAllowed = pumpType.specialBasalDurations
.hasCapability(PumpCapability.BasalRate_Duration30minAllowed)
isSetBasalProfileCapable = pumpCapability.hasCapability(PumpCapability.BasalProfileSet)
basalStep = pumpType.baseBasalStep
basalMinimumRate = pumpType.baseBasalMinValue
isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill)
isBatteryReplaceable = pumpCapability.hasCapability(PumpCapability.ReplaceBattery)
storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo)
supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD)
needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad)
is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min)
hasCustomUnreachableAlertCheck = pumpType.hasCustomUnreachableAlertCheck
}
companion object {
const val NONE = 0
const val PERCENT = 0x01
const val ABSOLUTE = 0x02
}
init {
resetSettings()
}
}

View file

@ -1,21 +0,0 @@
package info.nightscout.androidaps.logging;
import android.os.Bundle;
/**
* Created by mike on 14.08.2017.
*/
public class BundleLogger {
public static String log(Bundle bundle) {
if (bundle == null) {
return null;
}
String string = "Bundle{";
for (String key : bundle.keySet()) {
string += " " + key + " => " + bundle.get(key) + ";";
}
string += " }Bundle";
return string;
}
}

View file

@ -0,0 +1,18 @@
package info.nightscout.androidaps.logging
import android.os.Bundle
object BundleLogger {
fun log(bundle: Bundle?): String {
if (bundle == null) {
return "null"
}
var string = "Bundle{"
for (key in bundle.keySet()) {
string += " " + key + " => " + bundle[key] + ";"
}
string += " }Bundle"
return string
}
}

View file

@ -1,30 +0,0 @@
package info.nightscout.androidaps.plugins.common;
public enum ManufacturerType {
AndroidAPS("AndroidAPS"),
Medtronic("Medtronic"),
Sooil("SOOIL"),
Tandem("Tandem"),
Insulet("Insulet"),
Animas("Animas"),
Cellnovo("Cellnovo"),
Roche("Roche"),
Ypsomed("Ypsomed");
private final String description;
ManufacturerType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}

View file

@ -0,0 +1,13 @@
package info.nightscout.androidaps.plugins.common
enum class ManufacturerType(val description: String) {
AndroidAPS("AndroidAPS"),
Medtronic("Medtronic"),
Sooil("SOOIL"),
Tandem("Tandem"),
Insulet("Insulet"),
Animas("Animas"),
Cellnovo("Cellnovo"),
Roche("Roche"),
Ypsomed("Ypsomed");
}

View file

@ -18,6 +18,9 @@ class ConstraintChecker @Inject constructor(private val activePlugin: ActivePlug
fun isClosedLoopAllowed(): Constraint<Boolean> = fun isClosedLoopAllowed(): Constraint<Boolean> =
isClosedLoopAllowed(Constraint(true)) isClosedLoopAllowed(Constraint(true))
fun isLgsAllowed(): Constraint<Boolean> =
isLgsAllowed(Constraint(true))
fun isAutosensModeEnabled(): Constraint<Boolean> = fun isAutosensModeEnabled(): Constraint<Boolean> =
isAutosensModeEnabled(Constraint(true)) isAutosensModeEnabled(Constraint(true))
@ -77,6 +80,16 @@ class ConstraintChecker @Inject constructor(private val activePlugin: ActivePlug
return value return value
} }
override fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(ConstraintsInterface::class.java)
for (p in constraintsPlugins) {
val constraint = p as ConstraintsInterface
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue
constraint.isLgsAllowed(value)
}
return value
}
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> { override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(ConstraintsInterface::class.java) val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(ConstraintsInterface::class.java)
for (p in constraintsPlugins) { for (p in constraintsPlugins) {

View file

@ -88,7 +88,7 @@ class ProfileFunctionImplementation @Inject constructor(
} }
if (activeTreatments.profileSwitchesFromHistory.size() > 0) { if (activeTreatments.profileSwitchesFromHistory.size() > 0) {
val bundle = Bundle() val bundle = Bundle()
bundle.putString(FirebaseAnalytics.Param.ITEM_LIST_ID, "CatchedError") bundle.putString(FirebaseAnalytics.Param.ITEM_LIST_ID, "CaughtError")
bundle.putString(FirebaseAnalytics.Param.START_DATE, time.toString()) bundle.putString(FirebaseAnalytics.Param.START_DATE, time.toString())
bundle.putString(FirebaseAnalytics.Param.ITEM_LIST_NAME, activeTreatments.profileSwitchesFromHistory.toString()) bundle.putString(FirebaseAnalytics.Param.ITEM_LIST_NAME, activeTreatments.profileSwitchesFromHistory.toString())
fabricPrivacy.logCustom(bundle) fabricPrivacy.logCustom(bundle)

View file

@ -25,7 +25,7 @@ class RunningConfiguration @Inject constructor(
) { ) {
private var counter = 0 private var counter = 0
private val every = 20 // Send only every 20 devicestatus to save traffic private val every = 20 // Send only every 20 device status to save traffic
// called in AAPS mode only // called in AAPS mode only
fun configuration(): JSONObject { fun configuration(): JSONObject {
@ -83,7 +83,7 @@ class RunningConfiguration @Inject constructor(
val pumpType = JsonHelper.safeGetString(configuration, "pump", PumpType.GenericAAPS.description) val pumpType = JsonHelper.safeGetString(configuration, "pump", PumpType.GenericAAPS.description)
sp.putString(R.string.key_virtualpump_type, pumpType) sp.putString(R.string.key_virtualpump_type, pumpType)
activePlugin.activePump.pumpDescription.setPumpDescription(PumpType.getByDescription(pumpType)) activePlugin.activePump.pumpDescription.setPumpDescription(PumpType.getByDescription(pumpType))
aapsLogger.debug(LTag.CORE, "Changing pump type to ${pumpType}") aapsLogger.debug(LTag.CORE, "Changing pump type to $pumpType")
} }
if (configuration.has("overviewConfiguration")) if (configuration.has("overviewConfiguration"))

View file

@ -107,7 +107,7 @@ class VersionCheckerUtils @Inject constructor(
val now = System.currentTimeMillis() val now = System.currentTimeMillis()
if (now > sp.getLong(R.string.key_last_versionchecker_warning, 0) + WARN_EVERY) { if (now > sp.getLong(R.string.key_last_versionchecker_warning, 0) + WARN_EVERY) {
aapsLogger.debug(LTag.CORE, "Version $currentVersion outdated. Found $newVersion") aapsLogger.debug(LTag.CORE, "Version $currentVersion outdated. Found $newVersion")
val notification = Notification(Notification.NEWVERSIONDETECTED, resourceHelper.gs(R.string.versionavailable, newVersion.toString()), Notification.LOW) val notification = Notification(Notification.NEW_VERSION_DETECTED, resourceHelper.gs(R.string.versionavailable, newVersion.toString()), Notification.LOW)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
sp.putLong(R.string.key_last_versionchecker_warning, now) sp.putLong(R.string.key_last_versionchecker_warning, now)
} }
@ -140,7 +140,7 @@ fun String.numericVersionPart(): String =
"(((\\d+)\\.)+(\\d+))(\\D(.*))?".toRegex().matchEntire(this)?.groupValues?.getOrNull(1) "(((\\d+)\\.)+(\\d+))(\\D(.*))?".toRegex().matchEntire(this)?.groupValues?.getOrNull(1)
?: "" ?: ""
fun findVersion(file: String?): String? { @Suppress("unused") fun findVersion(file: String?): String? {
val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex() val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex()
return file?.lines()?.filter { regex.matches(it) }?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull() return file?.lines()?.filter { regex.matches(it) }?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull()
} }

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.nsclient; package info.nightscout.androidaps.plugins.general.nsclient;
import android.content.Context;
import android.os.Build; import android.os.Build;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -212,7 +211,7 @@ public class NSUpload {
JSONObject requested = new JSONObject(); JSONObject requested = new JSONObject();
if (lastRun.getTbrSetByPump() != null && lastRun.getTbrSetByPump().enacted) { // enacted if (lastRun.getTbrSetByPump() != null && lastRun.getTbrSetByPump().getEnacted()) { // enacted
deviceStatus.enacted = lastRun.getRequest().json(); deviceStatus.enacted = lastRun.getRequest().json();
deviceStatus.enacted.put("rate", lastRun.getTbrSetByPump().json(profile).get("rate")); deviceStatus.enacted.put("rate", lastRun.getTbrSetByPump().json(profile).get("rate"));
deviceStatus.enacted.put("duration", lastRun.getTbrSetByPump().json(profile).get("duration")); deviceStatus.enacted.put("duration", lastRun.getTbrSetByPump().json(profile).get("duration"));
@ -222,11 +221,11 @@ public class NSUpload {
requested.put("temp", "absolute"); requested.put("temp", "absolute");
deviceStatus.enacted.put("requested", requested); deviceStatus.enacted.put("requested", requested);
} }
if (lastRun.getTbrSetByPump() != null && lastRun.getTbrSetByPump().enacted) { // enacted if (lastRun.getTbrSetByPump() != null && lastRun.getTbrSetByPump().getEnacted()) { // enacted
if (deviceStatus.enacted == null) { if (deviceStatus.enacted == null) {
deviceStatus.enacted = lastRun.getRequest().json(); deviceStatus.enacted = lastRun.getRequest().json();
} }
deviceStatus.enacted.put("smb", lastRun.getTbrSetByPump().bolusDelivered); deviceStatus.enacted.put("smb", lastRun.getTbrSetByPump().getBolusDelivered());
requested.put("smb", lastRun.getRequest().getSmb()); requested.put("smb", lastRun.getRequest().getSmb());
deviceStatus.enacted.put("requested", requested); deviceStatus.enacted.put("requested", requested);
} }
@ -240,9 +239,7 @@ public class NSUpload {
} }
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL; deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
JSONObject pumpstatus = pumpInterface.getJSONStatus(profile, profileName, version); JSONObject pumpstatus = pumpInterface.getJSONStatus(profile, profileName, version);
if (pumpstatus != null) { deviceStatus.pump = pumpstatus;
deviceStatus.pump = pumpstatus;
}
deviceStatus.uploaderBattery = receiverStatusStore.getBatteryLevel(); deviceStatus.uploaderBattery = receiverStatusStore.getBatteryLevel();

View file

@ -1,145 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.notifications;
import androidx.annotation.NonNull;
import info.nightscout.androidaps.utils.T;
public class Notification {
// TODO join with NotificationWithAction after change to enums
public static final int URGENT = 0;
public static final int NORMAL = 1;
public static final int LOW = 2;
public static final int INFO = 3;
public static final int ANNOUNCEMENT = 4;
public static final int PROFILE_SET_FAILED = 0;
public static final int PROFILE_SET_OK = 1;
public static final int EASYMODE_ENABLED = 2;
public static final int EXTENDED_BOLUS_DISABLED = 3;
public static final int UD_MODE_ENABLED = 4;
public static final int PROFILE_NOT_SET_NOT_INITIALIZED = 5;
public static final int FAILED_UDPATE_PROFILE = 6;
public static final int BASAL_VALUE_BELOW_MINIMUM = 7;
public static final int OLD_NS = 9;
public static final int INVALID_PHONE_NUMBER = 10;
public static final int INVALID_MESSAGE_BODY = 11;
public static final int APPROACHING_DAILY_LIMIT = 12;
public static final int NSCLIENT_NO_WRITE_PERMISSION = 13;
public static final int MISSING_SMS_PERMISSION = 14;
public static final int PUMPERROR = 15;
public static final int WRONGSERIALNUMBER = 16;
public static final int NSANNOUNCEMENT = 18;
public static final int NSALARM = 19;
public static final int NSURGENTALARM = 20;
public static final int SHORT_DIA = 21;
public static final int TOAST_ALARM = 22;
public static final int WRONGBASALSTEP = 23;
public static final int WRONG_DRIVER = 24;
public static final int COMBO_PUMP_ALARM = 25;
public static final int PUMP_UNREACHABLE = 26;
public static final int BG_READINGS_MISSED = 27;
public static final int UNSUPPORTED_FIRMWARE = 28;
public static final int MINIMAL_BASAL_VALUE_REPLACED = 29;
public static final int BASAL_PROFILE_NOT_ALIGNED_TO_HOURS = 30;
public static final int ZERO_VALUE_IN_PROFILE = 31;
public static final int PROFILE_SWITCH_MISSING = 32;
public static final int NOT_ENG_MODE_OR_RELEASE = 33;
public static final int WRONG_PUMP_PASSWORD = 34;
public static final int PERMISSION_STORAGE = 35;
public static final int PERMISSION_LOCATION = 36;
public static final int PERMISSION_BATTERY = 37;
public static final int PERMISSION_SMS = 38;
public static final int MAXIMUM_BASAL_VALUE_REPLACED = 39;
public static final int NSMALFUNCTION = 40;
public static final int NEWVERSIONDETECTED = 41;
public static final int SENDLOGFILES = 42;
public static final int DEVICENOTPAIRED = 43;
public static final int MEDTRONIC_PUMP_ALARM = 44;
public static final int RILEYLINK_CONNECTION = 45;
public static final int PERMISSION_PHONESTATE = 46;
public static final int INSIGHT_DATE_TIME_UPDATED = 47;
public static final int INSIGHT_TIMEOUT_DURING_HANDSHAKE = 48;
public static final int DST_LOOP_DISABLED = 49;
public static final int DST_IN_24H = 50;
public static final int DISKFULL = 51;
public static final int OLDVERSION = 52;
public static final int OVER_24H_TIME_CHANGE_REQUESTED = 54;
public static final int INVALID_VERSION = 55;
public static final int PERMISSION_SYSTEM_WINDOW = 56;
public static final int TIME_OR_TIMEZONE_CHANGE = 58;
public static final int OMNIPOD_POD_NOT_ATTACHED = 59;
public static final int CARBS_REQUIRED = 60;
public static final int OMNIPOD_POD_SUSPENDED = 61;
public static final int OMNIPOD_POD_ALERTS_UPDATED = 62;
public static final int OMNIPOD_POD_ALERTS = 63;
public static final int OMNIPOD_TBR_ALERTS = 64;
public static final int OMNIPOD_POD_FAULT = 66;
public static final int OMNIPOD_UNCERTAIN_SMB = 67;
public static final int OMNIPOD_UNKNOWN_TBR = 68;
public static final int OMNIPOD_STARTUP_STATUS_REFRESH_FAILED = 69;
public static final int OMNIPOD_TIME_OUT_OF_SYNC = 70;
public static final int IMPORTANCE_HIGH = 2;
public static final String CATEGORY_ALARM = "alarm";
public static final int USERMESSAGE = 1000;
public int id;
public long date;
public String text;
public int level;
public long validTo = 0;
public Integer soundId = null;
protected Runnable action = null;
protected int buttonText = 0;
public Notification() {
}
public Notification(int id, long date, String text, int level, long validTo) {
this.id = id;
this.date = date;
this.text = text;
this.level = level;
this.validTo = validTo;
}
public Notification(int id, String text, int level, int validMinutes) {
this.id = id;
this.date = System.currentTimeMillis();
this.text = text;
this.level = level;
this.validTo = System.currentTimeMillis() + T.mins(validMinutes).msecs();
}
public Notification(int id, @NonNull String text, int level) {
this.id = id;
this.date = System.currentTimeMillis();
this.text = text;
this.level = level;
}
public Notification(int id) {
this.id = id;
this.date = System.currentTimeMillis();
}
public Notification text(String text) {
this.text = text;
return this;
}
public Notification level(int level) {
this.level = level;
return this;
}
public Notification sound(int soundId) {
this.soundId = soundId;
return this;
}
}

View file

@ -0,0 +1,130 @@
package info.nightscout.androidaps.plugins.general.overview.notifications
import androidx.annotation.RawRes
import info.nightscout.androidaps.utils.T
open class Notification {
var id = 0
var date: Long = 0
var text: String? = null
var level = 0
var validTo: Long = 0
@RawRes var soundId: Int? = null
var action: Runnable? = null
var buttonText = 0
constructor()
constructor(id: Int, date: Long, text: String, level: Int, validTo: Long) {
this.id = id
this.date = date
this.text = text
this.level = level
this.validTo = validTo
}
constructor(id: Int, text: String, level: Int, validMinutes: Int) {
this.id = id
date = System.currentTimeMillis()
this.text = text
this.level = level
validTo = System.currentTimeMillis() + T.mins(validMinutes.toLong()).msecs()
}
constructor(id: Int, text: String, level: Int) {
this.id = id
date = System.currentTimeMillis()
this.text = text
this.level = level
}
constructor(id: Int) {
this.id = id
date = System.currentTimeMillis()
}
fun text(text: String): Notification = this.also { it.text = text }
fun level(level: Int): Notification = this.also { it.level = level }
fun sound(soundId: Int): Notification = this.also { it.soundId = soundId }
companion object {
// Hard to convert to enums because for NS notifications we create dynamic ID
const val URGENT = 0
const val NORMAL = 1
const val LOW = 2
const val INFO = 3
const val ANNOUNCEMENT = 4
const val PROFILE_SET_FAILED = 0
const val PROFILE_SET_OK = 1
const val EASY_MODE_ENABLED = 2
const val EXTENDED_BOLUS_DISABLED = 3
const val UD_MODE_ENABLED = 4
const val PROFILE_NOT_SET_NOT_INITIALIZED = 5
const val FAILED_UPDATE_PROFILE = 6
const val BASAL_VALUE_BELOW_MINIMUM = 7
const val OLD_NS = 9
const val INVALID_PHONE_NUMBER = 10
const val INVALID_MESSAGE_BODY = 11
const val APPROACHING_DAILY_LIMIT = 12
const val NSCLIENT_NO_WRITE_PERMISSION = 13
const val MISSING_SMS_PERMISSION = 14
const val PUMP_ERROR = 15
const val WRONG_SERIAL_NUMBER = 16
const val NS_ANNOUNCEMENT = 18
const val NS_ALARM = 19
const val NS_URGENT_ALARM = 20
const val SHORT_DIA = 21
const val TOAST_ALARM = 22
const val WRONG_BASAL_STEP = 23
const val WRONG_DRIVER = 24
const val COMBO_PUMP_ALARM = 25
const val PUMP_UNREACHABLE = 26
const val BG_READINGS_MISSED = 27
const val UNSUPPORTED_FIRMWARE = 28
const val MINIMAL_BASAL_VALUE_REPLACED = 29
const val BASAL_PROFILE_NOT_ALIGNED_TO_HOURS = 30
const val ZERO_VALUE_IN_PROFILE = 31
const val PROFILE_SWITCH_MISSING = 32
@Suppress("unused") const val NOT_ENG_MODE_OR_RELEASE = 33
const val WRONG_PUMP_PASSWORD = 34
const val PERMISSION_STORAGE = 35
const val PERMISSION_LOCATION = 36
const val PERMISSION_BATTERY = 37
const val PERMISSION_SMS = 38
const val MAXIMUM_BASAL_VALUE_REPLACED = 39
const val NS_MALFUNCTION = 40
const val NEW_VERSION_DETECTED = 41
const val SEND_LOGFILES = 42
const val DEVICE_NOT_PAIRED = 43
const val MEDTRONIC_PUMP_ALARM = 44
const val RILEYLINK_CONNECTION = 45
const val PERMISSION_PHONE_STATE = 46
const val INSIGHT_DATE_TIME_UPDATED = 47
const val INSIGHT_TIMEOUT_DURING_HANDSHAKE = 48
const val DST_LOOP_DISABLED = 49
const val DST_IN_24H = 50
const val DISK_FULL = 51
const val OLD_VERSION = 52
const val OVER_24H_TIME_CHANGE_REQUESTED = 54
const val INVALID_VERSION = 55
const val PERMISSION_SYSTEM_WINDOW = 56
const val TIME_OR_TIMEZONE_CHANGE = 58
const val OMNIPOD_POD_NOT_ATTACHED = 59
const val CARBS_REQUIRED = 60
const val OMNIPOD_POD_SUSPENDED = 61
const val OMNIPOD_POD_ALERTS_UPDATED = 62
const val OMNIPOD_POD_ALERTS = 63
const val OMNIPOD_TBR_ALERTS = 64
const val OMNIPOD_POD_FAULT = 66
const val OMNIPOD_UNCERTAIN_SMB = 67
const val OMNIPOD_UNKNOWN_TBR = 68
const val OMNIPOD_STARTUP_STATUS_REFRESH_FAILED = 69
const val OMNIPOD_TIME_OUT_OF_SYNC = 70
const val USER_MESSAGE = 1000
const val IMPORTANCE_HIGH = 2
const val CATEGORY_ALARM = "alarm"
}
}

View file

@ -4,7 +4,7 @@ class NotificationUserMessage (text :String): Notification() {
init { init {
var hash = text.hashCode() var hash = text.hashCode()
if (hash < USERMESSAGE) hash += USERMESSAGE if (hash < USER_MESSAGE) hash += USER_MESSAGE
id = hash id = hash
date = System.currentTimeMillis() date = System.currentTimeMillis()
this.text = text this.text = text

View file

@ -375,7 +375,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
ret += "LastConn: " + agoMin + " min ago\n"; ret += "LastConn: " + agoMin + " min ago\n";
} }
if (getPumpStatusData().lastBolusTime != null && getPumpStatusData().lastBolusTime.getTime() != 0) { if (getPumpStatusData().lastBolusTime != null && getPumpStatusData().lastBolusTime.getTime() != 0) {
ret += "LastBolus: " + DecimalFormatter.to2Decimal(getPumpStatusData().lastBolusAmount) + "U @" + // ret += "LastBolus: " + DecimalFormatter.INSTANCE.to2Decimal(getPumpStatusData().lastBolusAmount) + "U @" + //
android.text.format.DateFormat.format("HH:mm", getPumpStatusData().lastBolusTime) + "\n"; android.text.format.DateFormat.format("HH:mm", getPumpStatusData().lastBolusTime) + "\n";
} }
TemporaryBasal activeTemp = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis()); TemporaryBasal activeTemp = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis());
@ -392,7 +392,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
// + pumpStatus.maxDailyTotalUnits + " U\n"; // + pumpStatus.maxDailyTotalUnits + " U\n";
// } // }
ret += "IOB: " + getPumpStatusData().iob + "U\n"; ret += "IOB: " + getPumpStatusData().iob + "U\n";
ret += "Reserv: " + DecimalFormatter.to0Decimal(getPumpStatusData().reservoirRemainingUnits) + "U\n"; ret += "Reserv: " + DecimalFormatter.INSTANCE.to0Decimal(getPumpStatusData().reservoirRemainingUnits) + "U\n";
ret += "Batt: " + getPumpStatusData().batteryRemaining + "\n"; ret += "Batt: " + getPumpStatusData().batteryRemaining + "\n";
return ret; return ret;
} }
@ -406,7 +406,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
// neither carbs nor bolus requested // neither carbs nor bolus requested
aapsLogger.error("deliverTreatment: Invalid input"); aapsLogger.error("deliverTreatment: Invalid input");
return new PumpEnactResult(getInjector()).success(false).enacted(false).bolusDelivered(0d).carbsDelivered(0d) return new PumpEnactResult(getInjector()).success(false).enacted(false).bolusDelivered(0d).carbsDelivered(0d)
.comment(getResourceHelper().gs(R.string.invalidinput)); .comment(R.string.invalidinput);
} else if (detailedBolusInfo.insulin > 0) { } else if (detailedBolusInfo.insulin > 0) {
// bolus needed, ask pump to deliver it // bolus needed, ask pump to deliver it
return deliverBolus(detailedBolusInfo); return deliverBolus(detailedBolusInfo);
@ -426,7 +426,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment."); aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment.");
return new PumpEnactResult(getInjector()).success(true).enacted(true).bolusDelivered(0d) return new PumpEnactResult(getInjector()).success(true).enacted(true).bolusDelivered(0d)
.carbsDelivered(detailedBolusInfo.carbs).comment(getResourceHelper().gs(R.string.common_resultok)); .carbsDelivered(detailedBolusInfo.carbs).comment(R.string.common_resultok);
} }
} finally { } finally {
triggerUIChange(); triggerUIChange();
@ -471,6 +471,6 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
protected abstract void triggerUIChange(); protected abstract void triggerUIChange();
private PumpEnactResult getOperationNotSupportedWithCustomText(int resourceId) { private PumpEnactResult getOperationNotSupportedWithCustomText(int resourceId) {
return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(getResourceHelper().gs(resourceId)); return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(resourceId);
} }
} }

View file

@ -1,67 +0,0 @@
package info.nightscout.androidaps.utils;
import java.text.DecimalFormat;
import info.nightscout.androidaps.core.R;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
/**
* Created by mike on 11.07.2016.
*/
public class DecimalFormatter {
private static final DecimalFormat format0dec = new DecimalFormat("0");
private static final DecimalFormat format1dec = new DecimalFormat("0.0");
private static final DecimalFormat format2dec = new DecimalFormat("0.00");
private static final DecimalFormat format3dec = new DecimalFormat("0.000");
public static String to0Decimal(double value) {
return format0dec.format(value);
}
public static String to0Decimal(double value, String unit) {
return format0dec.format(value) + unit;
}
public static String to1Decimal(double value) {
return format1dec.format(value);
}
public static String to1Decimal(double value, String unit) {
return format1dec.format(value) + unit;
}
public static String to2Decimal(double value) {
return format2dec.format(value);
}
public static String to2Decimal(double value, String unit) {
return format2dec.format(value) + unit;
}
public static String to3Decimal(double value) {
return format3dec.format(value);
}
public static String to3Decimal(double value, String unit) {
return format3dec.format(value) + unit;
}
public static String toPumpSupportedBolus(double value, PumpInterface pump) {
return pump.getPumpDescription().bolusStep <= 0.051
? to2Decimal(value)
: to1Decimal(value);
}
public static String toPumpSupportedBolus(double value, PumpInterface pump, ResourceHelper resourceHelper) {
return pump.getPumpDescription().bolusStep <= 0.051
? resourceHelper.gs(R.string.formatinsulinunits, value)
: resourceHelper.gs(R.string.formatinsulinunits1, value);
}
public static DecimalFormat pumpSupportedBolusFormat(PumpInterface pump) {
return pump.getPumpDescription().bolusStep <= 0.051
? new DecimalFormat("0.00")
: new DecimalFormat("0.0");
}
}

View file

@ -0,0 +1,26 @@
package info.nightscout.androidaps.utils
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.interfaces.PumpInterface
import info.nightscout.androidaps.utils.resources.ResourceHelper
import java.text.DecimalFormat
object DecimalFormatter {
private val format0dec = DecimalFormat("0")
private val format1dec = DecimalFormat("0.0")
private val format2dec = DecimalFormat("0.00")
private val format3dec = DecimalFormat("0.000")
fun to0Decimal(value: Double): String = format0dec.format(value)
fun to0Decimal(value: Double, unit: String): String = format0dec.format(value) + unit
fun to1Decimal(value: Double): String = format1dec.format(value)
fun to1Decimal(value: Double, unit: String): String = format1dec.format(value) + unit
fun to2Decimal(value: Double): String = format2dec.format(value)
fun to2Decimal(value: Double, unit: String): String = format2dec.format(value) + unit
fun to3Decimal(value: Double): String = format3dec.format(value)
fun to3Decimal(value: Double, unit: String): String = format3dec.format(value) + unit
fun toPumpSupportedBolus(value: Double, pump: PumpInterface): String = if (pump.pumpDescription.bolusStep <= 0.051) to2Decimal(value) else to1Decimal(value)
fun toPumpSupportedBolus(value: Double, pump: PumpInterface, resourceHelper: ResourceHelper): String = if (pump.pumpDescription.bolusStep <= 0.051) resourceHelper.gs(R.string.formatinsulinunits, value) else resourceHelper.gs(R.string.formatinsulinunits1, value)
fun pumpSupportedBolusFormat(pump: PumpInterface): DecimalFormat = if (pump.pumpDescription.bolusStep <= 0.051) DecimalFormat("0.00") else DecimalFormat("0.0")
}

View file

@ -106,101 +106,6 @@ fun Action.stringId(): Int {
} }
} }
fun Action.colorId(): Int {
return when (this) {
Action.EXTENDED_CARBS -> R.color.carbs
Action.TEMP_BASAL -> R.color.basal
Action.TT -> R.color.tempTargetConfirmation
Action.TT_ACTIVITY -> R.color.tempTargetConfirmation
Action.TT_EATING_SOON -> R.color.tempTargetConfirmation
Action.TT_HYPO -> R.color.tempTargetConfirmation
Action.NEW_PROFILE -> R.color.white
Action.CLONE_PROFILE -> R.color.white
Action.STORE_PROFILE -> R.color.white
Action.PROFILE_SWITCH -> R.color.white
Action.PROFILE_SWITCH_CLONED -> R.color.white
Action.CLOSED_LOOP_MODE -> R.color.loopClosed
Action.LGS_LOOP_MODE -> R.color.loopClosed
Action.OPEN_LOOP_MODE -> R.color.loopOpened
Action.LOOP_DISABLED -> R.color.loopDisabled
Action.LOOP_ENABLED -> R.color.loopClosed
Action.RECONNECT -> R.color.loopDisconnected
Action.DISCONNECT_15M -> R.color.loopDisconnected
Action.DISCONNECT_30M -> R.color.loopDisconnected
Action.DISCONNECT_1H -> R.color.loopDisconnected
Action.DISCONNECT_2H -> R.color.loopDisconnected
Action.DISCONNECT_3H -> R.color.loopDisconnected
Action.RESUME -> R.color.loopClosed
Action.SUSPEND_1H -> R.color.loopSuspended
Action.SUSPEND_2H -> R.color.loopSuspended
Action.SUSPEND_3H -> R.color.loopSuspended
Action.SUSPEND_10H -> R.color.loopSuspended
Action.HW_PUMP_ALLOWED -> R.color.defaulttext
Action.CLEAR_PAIRING_KEYS -> R.color.defaulttext
Action.ACCEPTS_TEMP_BASAL -> R.color.basal
Action.CANCEL_TEMP_BASAL -> R.color.basal
Action.CANCEL_EXTENDED_BOLUS -> R.color.extendedBolus
Action.CANCEL_TT -> R.color.tempTargetConfirmation
Action.CAREPORTAL -> R.color.notificationAnnouncement
Action.CALIBRATION -> R.color.calibration
Action.INSULIN_CHANGE -> R.color.iob
Action.PRIME_BOLUS -> R.color.defaulttext
Action.SITE_CHANGE -> R.color.defaulttext
Action.TREATMENT -> R.color.defaulttext
Action.CAREPORTAL_NS_REFRESH -> R.color.notificationAnnouncement
Action.PROFILE_SWITCH_NS_REFRESH -> R.color.white
Action.TREATMENTS_NS_REFRESH -> R.color.defaulttext
Action.TT_NS_REFRESH -> R.color.tempTargetConfirmation
Action.AUTOMATION_REMOVED -> R.color.defaulttext
Action.BG_REMOVED -> R.color.calibration
Action.CAREPORTAL_REMOVED -> R.color.notificationAnnouncement
Action.EXTENDED_BOLUS_REMOVED -> R.color.extendedBolus
Action.FOOD_REMOVED -> R.color.carbs
Action.PROFILE_REMOVED -> R.color.white
Action.PROFILE_SWITCH_REMOVED -> R.color.white
Action.RESTART_EVENTS_REMOVED -> R.color.defaulttext
Action.TREATMENT_REMOVED -> R.color.defaulttext
Action.TT_REMOVED -> R.color.tempTargetConfirmation
Action.NS_PAUSED -> R.color.defaulttext
Action.NS_QUEUE_CLEARED -> R.color.defaulttext
Action.NS_SETTINGS_COPIED -> R.color.defaulttext
Action.ERROR_DIALOG_OK -> R.color.defaulttext
Action.ERROR_DIALOG_MUTE -> R.color.defaulttext
Action.ERROR_DIALOG_MUTE_5MIN -> R.color.defaulttext
Action.OBJECTIVE_STARTED -> R.color.defaulttext
Action.OBJECTIVE_UNSTARTED -> R.color.defaulttext
Action.OBJECTIVES_SKIPPED -> R.color.defaulttext
Action.STAT_RESET -> R.color.defaulttext
Action.DELETE_LOGS -> R.color.defaulttext
Action.DELETE_FUTURE_TREATMENTS -> R.color.defaulttext
Action.EXPORT_SETTINGS -> R.color.defaulttext
Action.IMPORT_SETTINGS -> R.color.defaulttext
Action.RESET_DATABASES -> R.color.defaulttext
Action.EXPORT_DATABASES -> R.color.defaulttext
Action.IMPORT_DATABASES -> R.color.defaulttext
Action.OTP_EXPORT -> R.color.defaulttext
Action.OTP_RESET -> R.color.defaulttext
Action.SMS_BASAL -> R.color.basal
Action.SMS_BOLUS -> R.color.iob
Action.SMS_CAL -> R.color.calibration
Action.SMS_CARBS -> R.color.carbs
Action.SMS_EXTENDED_BOLUS -> R.color.extendedBolus
Action.SMS_LOOP_DISABLED -> R.color.loopDisabled
Action.SMS_LOOP_ENABLED -> R.color.loopClosed
Action.SMS_LOOP_RESUME -> R.color.loopClosed
Action.SMS_LOOP_SUSPEND -> R.color.loopSuspended
Action.SMS_PROFILE -> R.color.white
Action.SMS_PUMP_CONNECT -> R.color.loopDisconnected
Action.SMS_PUMP_DISCONNECT -> R.color.loopDisconnected
Action.SMS_SMS -> R.color.defaulttext
Action.SMS_TT -> R.color.tempTargetConfirmation
Action.TT_DELETED_FROM_NS -> R.color.tempTargetConfirmation
Action.TT_FROM_NS -> R.color.tempTargetConfirmation
Action.TT_CANCELED_FROM_NS -> R.color.tempTargetConfirmation
else -> R.color.defaulttext
}
}
fun ColorGroup.colorId(): Int { fun ColorGroup.colorId(): Int {
return when (this) { return when (this) {
ColorGroup.InsulinTreatment -> R.color.basal ColorGroup.InsulinTreatment -> R.color.basal

View file

@ -188,11 +188,11 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
}); });
} }
public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero, Button okButton, TextWatcher textWatcher) { public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formatter, boolean allowZero, Button okButton, TextWatcher textWatcher) {
if (this.textWatcher != null) { if (this.textWatcher != null) {
editText.removeTextChangedListener(this.textWatcher); editText.removeTextChangedListener(this.textWatcher);
} }
setParams(initValue, minValue, maxValue, step, formater, allowZero, okButton); setParams(initValue, minValue, maxValue, step, formatter, allowZero, okButton);
this.textWatcher = textWatcher; this.textWatcher = textWatcher;
if (textWatcher != null) if (textWatcher != null)
editText.addTextChangedListener(textWatcher); editText.addTextChangedListener(textWatcher);

View file

@ -179,6 +179,7 @@
<!-- BlePreCheck--> <!-- BlePreCheck-->
<string name="ble_not_supported">Bluetooth Low Energy not supported.</string> <string name="ble_not_supported">Bluetooth Low Energy not supported.</string>
<string name="ble_not_supported_or_not_paired">Bluetooth Low Energy not supported or device not paired.</string>
<string name="ble_not_enabled">Bluetooth not enabled.</string> <string name="ble_not_enabled">Bluetooth not enabled.</string>
<string name="location_not_found_title">Location Is Not Enabled</string> <string name="location_not_found_title">Location Is Not Enabled</string>
<string name="location_not_found_message">For Bluetooth discovery to work on newer devices, location must be enabled. AAPS does not track your location and it can be disabled after pairing is successful.</string> <string name="location_not_found_message">For Bluetooth discovery to work on newer devices, location must be enabled. AAPS does not track your location and it can be disabled after pairing is successful.</string>

View file

@ -0,0 +1,82 @@
package info.nightscout.androidaps
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.interfaces.TreatmentsInterface
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONObject
import org.junit.Before
import org.mockito.Mock
import org.powermock.core.classloader.annotations.PrepareForTest
@Suppress("SpellCheckingInspection")
@PrepareForTest(FabricPrivacy::class)
open class TestBaseWithProfile : TestBase() {
@Mock lateinit var activePluginProvider: ActivePluginProvider
@Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var treatmentsInterface: TreatmentsInterface
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var defaultValueHelper: DefaultValueHelper
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var configInterface: ConfigInterface
val rxBus = RxBusWrapper(aapsSchedulers)
val profileInjector = HasAndroidInjector {
AndroidInjector {
if (it is Profile) {
it.aapsLogger = aapsLogger
it.activePlugin = activePluginProvider
it.resourceHelper = resourceHelper
it.rxBus = rxBus
it.fabricPrivacy = fabricPrivacy
it.configInterface = configInterface
}
if (it is ProfileSwitch) {
it.treatmentsPlugin = treatmentsInterface
it.aapsLogger = aapsLogger
it.rxBus = rxBus
it.resourceHelper = resourceHelper
it.dateUtil = dateUtil
}
if (it is Treatment) {
it.activePlugin = activePluginProvider
it.profileFunction = profileFunction
it.defaultValueHelper = defaultValueHelper
it.resourceHelper = resourceHelper
}
}
}
private lateinit var validProfileJSON: String
lateinit var validProfile: Profile
@Suppress("PropertyName") val TESTPROFILENAME = "someProfile"
@Before
fun prepareMock() {
validProfileJSON = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
validProfile = Profile(profileInjector, JSONObject(validProfileJSON), Constants.MGDL)
}
fun getValidProfileStore(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStore(profileInjector, json)
}
}

View file

@ -0,0 +1,67 @@
package info.nightscout.androidaps
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.PumpInterface
import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.TimeChangeType
import org.json.JSONObject
@Suppress("MemberVisibilityCanBePrivate")
class TestPumpPlugin(val injector: HasAndroidInjector) : PumpInterface {
var connected = false
var isProfileSet = true
override fun isConnected() = connected
override fun isConnecting() = false
override fun isHandshakeInProgress() = false
val lastData = 0L
val baseBasal = 0.0
override val pumpDescription = PumpDescription()
override fun isInitialized(): Boolean = true
override fun isSuspended(): Boolean = false
override fun isBusy(): Boolean = false
override fun connect(reason: String) {
connected = true
}
override fun disconnect(reason: String) {
connected = false
}
override fun stopConnecting() {
connected = false
}
override fun waitForDisconnectionInSeconds(): Int = 0
override fun getPumpStatus(reason: String) {}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector)
override fun isThisProfileSet(profile: Profile): Boolean = isProfileSet
override fun lastDataTime(): Long = lastData
override val baseBasalRate: Double = baseBasal
override val reservoirLevel: Double = 0.0
override val batteryLevel: Int = 0
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun stopBolusDelivering() {}
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject()
override fun manufacturer(): ManufacturerType = ManufacturerType.AndroidAPS
override fun model(): PumpType = PumpType.GenericAAPS
override fun serialNumber(): String = "1"
override fun shortStatus(veryShort: Boolean): String = ""
override val isFakingTempsByExtendedBoluses: Boolean = false
override fun loadTDDs(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun canHandleDST(): Boolean = true
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {}
}

View file

@ -1,14 +1,12 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.data
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mock
import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@ -16,7 +14,7 @@ import org.powermock.modules.junit4.PowerMockRunner
* Created by mike on 19.03.2018. * Created by mike on 19.03.2018.
*/ */
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(MainApp::class, SP::class) @PrepareForTest(SP::class)
class ConstraintTest : TestBase() { class ConstraintTest : TestBase() {
@Test fun doTests() { @Test fun doTests() {

View file

@ -23,6 +23,7 @@ class IobTest {
Assert.assertTrue(a1 == a1) Assert.assertTrue(a1 == a1)
Assert.assertTrue(a1 == a2) Assert.assertTrue(a1 == a2)
Assert.assertFalse(a1 == b) Assert.assertFalse(a1 == b)
@Suppress("SENSELESS_COMPARISON")
Assert.assertFalse(a1 == null) Assert.assertFalse(a1 == null)
Assert.assertFalse(a1 == Any()) Assert.assertFalse(a1 == Any())
} }

View file

@ -6,11 +6,12 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@Suppress("SpellCheckingInspection")
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
class IobTotalTest { class IobTotalTest {
var now = DateUtil.now() var now = DateUtil.now()
@Test fun copytest() { @Test fun copyTest() {
val a = IobTotal(now) val a = IobTotal(now)
a.iob = 10.0 a.iob = 10.0
val b = a.copy() val b = a.copy()

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