Merge branch 'User_Entry_ValueWithUnits' into UE_ExportXML
This commit is contained in:
commit
f7f6f4b7c1
149 changed files with 2127 additions and 2464 deletions
|
@ -2,6 +2,22 @@
|
|||
<code_scheme name="Project" version="173">
|
||||
<option name="AUTODETECT_INDENTS" value="false" />
|
||||
<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="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />
|
||||
|
|
|
@ -13,6 +13,7 @@ jacoco {
|
|||
|
||||
tasks.withType(Test) {
|
||||
jacoco.includeNoLocationClasses = true
|
||||
jacoco.excludes = ['jdk.internal.*']
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
|
|
@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
|||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.utils.*
|
||||
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.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -314,7 +315,7 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
|
||||
bg = if (binding.bgcheckbox.isChecked) bg else 0.0
|
||||
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
|
||||
var cob = 0.0
|
||||
|
|
|
@ -18,6 +18,7 @@ import info.nightscout.androidaps.data.PumpEnactResult
|
|||
import info.nightscout.androidaps.db.CareportalEvent
|
||||
import info.nightscout.androidaps.db.Source
|
||||
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange
|
||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.events.EventNewBG
|
||||
import info.nightscout.androidaps.events.EventTempTargetChange
|
||||
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.EventNewNotification
|
||||
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.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.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
|
@ -76,8 +76,7 @@ open class LoopPlugin @Inject constructor(
|
|||
private val receiverStatusStore: ReceiverStatusStore,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val nsUpload: NSUpload,
|
||||
private val databaseHelper: DatabaseHelperInterface,
|
||||
private val hardLimits: HardLimits
|
||||
private val databaseHelper: DatabaseHelperInterface
|
||||
) : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.LOOP)
|
||||
.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 pump = activePlugin.activePump
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -509,18 +508,18 @@ open class LoopPlugin @Inject constructor(
|
|||
*/
|
||||
private fun applyTBRRequest(request: APSResult?, profile: Profile?, callback: Callback?) {
|
||||
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
|
||||
}
|
||||
val pump = activePlugin.activePump
|
||||
if (!pump.isInitialized()) {
|
||||
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
|
||||
}
|
||||
if (pump.isSuspended()) {
|
||||
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
|
||||
}
|
||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: $request")
|
||||
|
@ -534,13 +533,13 @@ open class LoopPlugin @Inject constructor(
|
|||
} else {
|
||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
|
||||
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) {
|
||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
|
||||
callback?.result(PumpEnactResult(injector).percent(request.percent)
|
||||
.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 {
|
||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: tempBasalPercent()")
|
||||
commandQueue.tempBasalPercent(request.percent, request.duration, false, profile!!, callback)
|
||||
|
@ -553,13 +552,13 @@ open class LoopPlugin @Inject constructor(
|
|||
} else {
|
||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
|
||||
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) {
|
||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
|
||||
callback?.result(PumpEnactResult(injector).absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
|
||||
.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 {
|
||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()")
|
||||
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()) {
|
||||
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
|
||||
callback?.result(PumpEnactResult(injector)
|
||||
.comment(resourceHelper.gs(R.string.smb_frequency_exceeded))
|
||||
.comment(R.string.smb_frequency_exceeded)
|
||||
.enacted(false).success(false))?.run()
|
||||
return
|
||||
}
|
||||
if (!pump.isInitialized()) {
|
||||
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
|
||||
}
|
||||
if (pump.isSuspended()) {
|
||||
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
|
||||
}
|
||||
aapsLogger.debug(LTag.APS, "applySMBRequest: $request")
|
||||
|
|
|
@ -113,20 +113,20 @@ open class OpenAPSAMAPlugin @Inject constructor(
|
|||
val maxIob = constraintChecker.getMaxIOBAllowed().also { maxIOBAllowedConstraint ->
|
||||
inputConstraints.copyReasons(maxIOBAllowedConstraint)
|
||||
}.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 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 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 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
|
||||
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet()
|
||||
if (tempTarget is ValueWrapper.Existing) {
|
||||
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())
|
||||
maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, hardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble())
|
||||
targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, hardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble())
|
||||
if (tempTarget is ValueWrapper.Existing) {
|
||||
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())
|
||||
maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble())
|
||||
targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble())
|
||||
}
|
||||
if (!hardLimits.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.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(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
|
||||
startPart = System.currentTimeMillis()
|
||||
|
|
|
@ -119,20 +119,20 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
|||
inputConstraints.copyReasons(maxIOBAllowedConstraint)
|
||||
}.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 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 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 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
|
||||
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil._now()).blockingGet()
|
||||
if (tempTarget is ValueWrapper.Existing) {
|
||||
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())
|
||||
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())
|
||||
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())
|
||||
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.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(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
|
||||
startPart = System.currentTimeMillis()
|
||||
|
|
|
@ -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)
|
||||
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 (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
|
||||
}
|
||||
}
|
|
@ -40,10 +40,10 @@ open class StorageConstraintPlugin @Inject constructor(
|
|||
aapsLogger.debug(LTag.CONSTRAINTS, "Internal storage free (Mb):$diskFree")
|
||||
if (diskFree < Constants.MINIMUM_FREE_SPACE) {
|
||||
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))
|
||||
} else {
|
||||
rxBus.send(EventDismissNotification(Notification.DISKFULL))
|
||||
rxBus.send(EventDismissNotification(Notification.DISK_FULL))
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ class VersionCheckerPlugin @Inject constructor(
|
|||
gracePeriod.old,
|
||||
gracePeriod.veryOld
|
||||
)
|
||||
val notification = Notification(Notification.OLDVERSION, message, Notification.NORMAL)
|
||||
val notification = Notification(Notification.OLD_VERSION, message, Notification.NORMAL)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -491,7 +491,7 @@ public class NSClientPlugin extends PluginBase {
|
|||
&& !enteredBy.equals(sp.getString("careportal_enteredby", "AndroidAPS"))) {
|
||||
boolean defaultVal = config.getNSCLIENT();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
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 EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins"));
|
||||
nsClientPlugin.pause(true);
|
||||
|
@ -508,8 +508,8 @@ public class NSClientService extends DaggerService {
|
|||
try {
|
||||
data = (JSONObject) args[0];
|
||||
rxBus.send(new EventNSClientNewLog("CLEARALARM", "received"));
|
||||
rxBus.send(new EventDismissNotification(Notification.NSALARM));
|
||||
rxBus.send(new EventDismissNotification(Notification.NSURGENTALARM));
|
||||
rxBus.send(new EventDismissNotification(Notification.NS_ALARM));
|
||||
rxBus.send(new EventDismissNotification(Notification.NS_URGENT_ALARM));
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString());
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
|
@ -710,8 +710,8 @@ public class NSClientService extends DaggerService {
|
|||
}
|
||||
// Was that sgv more less 5 mins ago ?
|
||||
if ((System.currentTimeMillis() - latestDateInReceivedData) / (60 * 1000L) < 5L) {
|
||||
rxBus.send(new EventDismissNotification(Notification.NSALARM));
|
||||
rxBus.send(new EventDismissNotification(Notification.NSURGENTALARM));
|
||||
rxBus.send(new EventDismissNotification(Notification.NS_ALARM));
|
||||
rxBus.send(new EventDismissNotification(Notification.NS_URGENT_ALARM));
|
||||
}
|
||||
handleNewSgv(sgvs, isDelta);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
|||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.extensions.directionToIcon
|
||||
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.resources.ResourceHelper
|
||||
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 overviewMenus: OverviewMenus
|
||||
@Inject lateinit var skinProvider: SkinProvider
|
||||
@Inject lateinit var trendCalculator: TrendCalculator
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@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.setTextColor(color)
|
||||
binding.infoLayout.arrow.setImageResource(lastBG.trendArrow.directionToIcon())
|
||||
binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(lastBG).directionToIcon())
|
||||
binding.infoLayout.arrow.setColorFilter(color)
|
||||
|
||||
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
||||
|
|
|
@ -68,7 +68,7 @@ class NotificationStore @Inject constructor(
|
|||
store.add(n)
|
||||
if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction)
|
||||
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())
|
||||
return true
|
||||
}
|
||||
|
@ -163,10 +163,10 @@ class NotificationStore @Inject constructor(
|
|||
@Suppress("SetTextI18n")
|
||||
holder.binding.text.text = dateUtil.timeString(notification.date) + " " + notification.text
|
||||
when (notification.level) {
|
||||
Notification.URGENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent))
|
||||
Notification.NORMAL -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal))
|
||||
Notification.LOW -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow))
|
||||
Notification.INFO -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo))
|
||||
Notification.URGENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationUrgent))
|
||||
Notification.NORMAL -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationNormal))
|
||||
Notification.LOW -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationLow))
|
||||
Notification.INFO -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationInfo))
|
||||
Notification.ANNOUNCEMENT -> holder.binding.cv.setBackgroundColor(resourceHelper.gc(R.color.notificationAnnouncement))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,21 +38,21 @@ class NotificationWithAction constructor(
|
|||
date = System.currentTimeMillis()
|
||||
when (nsAlarm.level()) {
|
||||
0 -> {
|
||||
id = NSANNOUNCEMENT
|
||||
id = NS_ANNOUNCEMENT
|
||||
level = ANNOUNCEMENT
|
||||
text = nsAlarm.message()
|
||||
validTo = System.currentTimeMillis() + T.mins(60).msecs()
|
||||
}
|
||||
|
||||
1 -> {
|
||||
id = NSALARM
|
||||
id = NS_ALARM
|
||||
level = NORMAL
|
||||
text = nsAlarm.title()
|
||||
soundId = R.raw.alarm
|
||||
}
|
||||
|
||||
2 -> {
|
||||
id = NSURGENTALARM
|
||||
id = NS_URGENT_ALARM
|
||||
level = URGENT
|
||||
text = nsAlarm.title()
|
||||
soundId = R.raw.urgentalarm
|
||||
|
|
|
@ -22,7 +22,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy
|
|||
import info.nightscout.androidaps.utils.resources.IconsProvider
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
|
@ -42,6 +42,7 @@ import info.nightscout.androidaps.queue.Callback
|
|||
import info.nightscout.androidaps.receivers.BundleStore
|
||||
import info.nightscout.androidaps.receivers.DataReceiver
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
|
|
@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
|||
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.utils.extensions.valueToUnits
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -52,6 +53,7 @@ import javax.inject.Singleton
|
|||
import kotlin.math.abs
|
||||
import kotlin.math.min
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@Singleton
|
||||
class ActionStringHandler @Inject constructor(
|
||||
private val sp: SP,
|
||||
|
@ -75,7 +77,6 @@ class ActionStringHandler @Inject constructor(
|
|||
private val danaRv2Plugin: DanaRv2Plugin,
|
||||
private val danaRSPlugin: DanaRSPlugin,
|
||||
private val danaPump: DanaPump,
|
||||
private val hardLimits: HardLimits,
|
||||
private val carbsGenerator: CarbsGenerator,
|
||||
private val dateUtil: DateUtil,
|
||||
private val config: Config,
|
||||
|
@ -84,7 +85,7 @@ class ActionStringHandler @Inject constructor(
|
|||
private val nsUpload: NSUpload
|
||||
) {
|
||||
|
||||
private val TIMEOUT = 65 * 1000
|
||||
private val timeout = 65 * 1000
|
||||
private var lastSentTimestamp: Long = 0
|
||||
private var lastConfirmActionString: String? = null
|
||||
private var lastBolusWizard: BolusWizard? = null
|
||||
|
@ -113,14 +114,11 @@ class ActionStringHandler @Inject constructor(
|
|||
// do the parsing and check constraints
|
||||
val act = actionString.split("\\s+".toRegex()).toTypedArray()
|
||||
if ("fillpreset" == act[0]) { ///////////////////////////////////// PRIME/FILL
|
||||
val amount: Double = if ("1" == act[1]) {
|
||||
sp.getDouble("fill_button1", 0.3)
|
||||
} else if ("2" == act[1]) {
|
||||
sp.getDouble("fill_button2", 0.0)
|
||||
} else if ("3" == act[1]) {
|
||||
sp.getDouble("fill_button3", 0.0)
|
||||
} else {
|
||||
return
|
||||
val amount: Double = when {
|
||||
"1" == act[1] -> sp.getDouble("fill_button1", 0.3)
|
||||
"2" == act[1] -> sp.getDouble("fill_button2", 0.0)
|
||||
"3" == act[1] -> sp.getDouble("fill_button3", 0.0)
|
||||
else -> return
|
||||
}
|
||||
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
|
||||
rMessage += resourceHelper.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U"
|
||||
|
@ -160,11 +158,11 @@ class ActionStringHandler @Inject constructor(
|
|||
low *= 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!")
|
||||
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!")
|
||||
return
|
||||
}
|
||||
|
@ -358,12 +356,11 @@ class ActionStringHandler @Inject constructor(
|
|||
message += "Today: " + DecimalFormatter.to2Decimal(tdd) + "U " + (DecimalFormatter.to0Decimal(100 * tdd / refTDD) + "%") + "\n"
|
||||
message += "\n"
|
||||
}
|
||||
var i = 0
|
||||
var weighted03 = 0.0
|
||||
var weighted05 = 0.0
|
||||
var weighted07 = 0.0
|
||||
historyList.reverse()
|
||||
for (record in historyList) {
|
||||
for ((i, record) in historyList.withIndex()) {
|
||||
val tdd = record.getTotal()
|
||||
if (i == 0) {
|
||||
weighted03 = tdd
|
||||
|
@ -374,7 +371,6 @@ class ActionStringHandler @Inject constructor(
|
|||
weighted05 = weighted05 * 0.5 + tdd * 0.5
|
||||
weighted03 = weighted03 * 0.7 + tdd * 0.3
|
||||
}
|
||||
i++
|
||||
}
|
||||
message += "weighted:\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
|
||||
if (lastConfirmActionString == null) return
|
||||
if (lastConfirmActionString != actionString) return
|
||||
if (System.currentTimeMillis() - lastSentTimestamp > TIMEOUT) return
|
||||
if (System.currentTimeMillis() - lastSentTimestamp > timeout) return
|
||||
lastConfirmActionString = null
|
||||
// do the parsing, check constraints and enact!
|
||||
val act = actionString.split("\\s+".toRegex()).toTypedArray()
|
||||
|
@ -578,7 +574,7 @@ class ActionStringHandler @Inject constructor(
|
|||
lastConfirmActionString = rAction
|
||||
return
|
||||
}
|
||||
//send profile to pumpe
|
||||
//send profile to pump
|
||||
activePlugin.activeTreatments.doProfileSwitch(0, percentage, timeshift)
|
||||
}
|
||||
|
||||
|
@ -642,8 +638,8 @@ class ActionStringHandler @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
@Synchronized private fun sendError(errormessage: String) {
|
||||
wearPlugin.requestActionConfirmation("ERROR", errormessage, "error")
|
||||
@Synchronized private fun sendError(errorMessage: String) {
|
||||
wearPlugin.requestActionConfirmation("ERROR", errorMessage, "error")
|
||||
lastSentTimestamp = System.currentTimeMillis()
|
||||
lastConfirmActionString = null
|
||||
lastBolusWizard = null
|
||||
|
|
|
@ -56,8 +56,8 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
|||
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper;
|
||||
import info.nightscout.androidaps.utils.GlucoseValueUtilsKt;
|
||||
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.sharedPreferences.SP;
|
||||
|
||||
|
@ -343,15 +343,15 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
|||
boolean detailed = sp.getBoolean(R.string.key_wear_detailed_delta, false);
|
||||
if (units.equals(Constants.MGDL)) {
|
||||
if (detailed) {
|
||||
deltastring += DecimalFormatter.to1Decimal(Math.abs(deltaMGDL));
|
||||
deltastring += DecimalFormatter.INSTANCE.to1Decimal(Math.abs(deltaMGDL));
|
||||
} else {
|
||||
deltastring += DecimalFormatter.to0Decimal(Math.abs(deltaMGDL));
|
||||
deltastring += DecimalFormatter.INSTANCE.to0Decimal(Math.abs(deltaMGDL));
|
||||
}
|
||||
} else {
|
||||
if (detailed) {
|
||||
deltastring += DecimalFormatter.to2Decimal(Math.abs(deltaMMOL));
|
||||
deltastring += DecimalFormatter.INSTANCE.to2Decimal(Math.abs(deltaMMOL));
|
||||
} else {
|
||||
deltastring += DecimalFormatter.to1Decimal(Math.abs(deltaMMOL));
|
||||
deltastring += DecimalFormatter.INSTANCE.to1Decimal(Math.abs(deltaMMOL));
|
||||
}
|
||||
}
|
||||
return deltastring;
|
||||
|
@ -689,14 +689,14 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
|||
treatmentsPlugin.updateTotalIOBTempBasals();
|
||||
IobTotal basalIob = treatmentsPlugin.getLastCalculationTempBasals().round();
|
||||
|
||||
iobSum = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob);
|
||||
iobDetail = "(" + DecimalFormatter.to2Decimal(bolusIob.iob) + "|" + DecimalFormatter.to2Decimal(basalIob.basaliob) + ")";
|
||||
iobSum = DecimalFormatter.INSTANCE.to2Decimal(bolusIob.iob + basalIob.basaliob);
|
||||
iobDetail = "(" + DecimalFormatter.INSTANCE.to2Decimal(bolusIob.iob) + "|" + DecimalFormatter.INSTANCE.to2Decimal(basalIob.basaliob) + ")";
|
||||
cobString = iobCobCalculatorPlugin.getCobInfo(false, "WatcherUpdaterService").generateCOBString();
|
||||
currentBasal = generateBasalString();
|
||||
|
||||
//bgi
|
||||
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);
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
|||
if (sp.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false)) {
|
||||
basalStringResult = "100%";
|
||||
} else {
|
||||
basalStringResult = DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h";
|
||||
basalStringResult = DecimalFormatter.INSTANCE.to2Decimal(profile.getBasal()) + "U/h";
|
||||
}
|
||||
}
|
||||
return basalStringResult;
|
||||
|
|
|
@ -159,7 +159,7 @@ class IobCobOref1Thread internal constructor(
|
|||
aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString())
|
||||
aapsLogger.debug(LTag.AUTOSENS, bucketedData.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))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
break
|
||||
|
@ -182,7 +182,7 @@ class IobCobOref1Thread internal constructor(
|
|||
aapsLogger.debug(autosensDataTable.toString())
|
||||
aapsLogger.debug(bucketedData.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))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
break
|
||||
|
|
|
@ -156,7 +156,7 @@ class IobCobThread @Inject internal constructor(
|
|||
aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString())
|
||||
aapsLogger.debug(LTag.AUTOSENS, bucketedData.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))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
break
|
||||
|
@ -179,7 +179,7 @@ class IobCobThread @Inject internal constructor(
|
|||
aapsLogger.debug(autosensDataTable.toString())
|
||||
aapsLogger.debug(bucketedData.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))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
break
|
||||
|
|
|
@ -22,10 +22,10 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
|||
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.text.DecimalFormat
|
||||
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)
|
||||
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) {
|
||||
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.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.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)
|
||||
} 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.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.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)
|
||||
}
|
||||
|
||||
// Spinner
|
||||
|
@ -222,7 +222,7 @@ class LocalProfileFragment : DaggerFragment() {
|
|||
disposable += rxBus
|
||||
.toObservable(EventLocalProfileChanged::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ build() },fabricPrivacy::logException)
|
||||
.subscribe({ build() }, fabricPrivacy::logException)
|
||||
build()
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ import info.nightscout.androidaps.utils.T
|
|||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.directionToIcon
|
||||
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.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.valueToUnitsString
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
|
|
@ -250,8 +250,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
if (!t.isValid) continue;
|
||||
if (t.date > time) continue;
|
||||
Iob tIOB = t.iobCalc(time, dia);
|
||||
total.iob += tIOB.iobContrib;
|
||||
total.activity += tIOB.activityContrib;
|
||||
total.iob += tIOB.getIobContrib();
|
||||
total.activity += tIOB.getActivityContrib();
|
||||
if (t.insulin > 0 && t.date > total.lastBolusTime)
|
||||
total.lastBolusTime = t.date;
|
||||
if (!t.isSMB) {
|
||||
|
@ -260,7 +260,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
long timeSinceTreatment = time - t.date;
|
||||
long snoozeTime = t.date + (long) (timeSinceTreatment * sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0));
|
||||
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.insulin = running * 5.0 / 60.0; // 5 min chunk
|
||||
Iob iob = treatment.iobCalc(time, profile.getDia());
|
||||
total.basaliob += iob.iobContrib;
|
||||
total.activity += iob.activityContrib;
|
||||
total.basaliob += iob.getIobContrib();
|
||||
total.activity += iob.getActivityContrib();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
holder.binding.clone.tag = profileSwitch
|
||||
holder.binding.name.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 {
|
||||
|
|
|
@ -128,7 +128,7 @@ open class CommandQueue @Inject constructor(
|
|||
}
|
||||
|
||||
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
|
||||
|
||||
|
@ -380,7 +380,7 @@ open class CommandQueue @Inject constructor(
|
|||
if (!buildHelper.isEngineeringModeOrRelease()) {
|
||||
val notification = Notification(Notification.NOT_ENG_MODE_OR_RELEASE, resourceHelper.gs(R.string.not_eng_mode_or_release), Notification.URGENT)
|
||||
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
|
||||
}
|
||||
*/
|
||||
|
@ -390,7 +390,7 @@ open class CommandQueue @Inject constructor(
|
|||
if (basalValue.value < activePlugin.get().activePump.pumpDescription.basalMinimumRate) {
|
||||
val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, resourceHelper.gs(R.string.basalvaluebelowminimum), Notification.URGENT)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,10 +91,10 @@ class AndroidPermission @Inject constructor(
|
|||
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_SMS))
|
||||
// Following is a bug in Android 8
|
||||
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)) }
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_PHONESTATE))
|
||||
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_PHONE_STATE))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
|
|||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
@Singleton
|
||||
class HardLimits @Inject constructor(
|
||||
|
@ -20,98 +22,75 @@ class HardLimits @Inject constructor(
|
|||
private val nsUpload: NSUpload
|
||||
) {
|
||||
|
||||
val CHILD = 0
|
||||
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)
|
||||
companion object {
|
||||
|
||||
// Very Hard Limits Ranges
|
||||
// First value is the Lowest and second value is the Highest a Limit can define
|
||||
val VERY_HARD_LIMIT_MIN_BG = intArrayOf(72, 180)
|
||||
val VERY_HARD_LIMIT_MAX_BG = intArrayOf(90, 270)
|
||||
val VERY_HARD_LIMIT_TARGET_BG = intArrayOf(80, 200)
|
||||
private const val CHILD = 0
|
||||
private const val TEENAGE = 1
|
||||
private const val ADULT = 2
|
||||
private const val RESISTANT_ADULT = 3
|
||||
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
|
||||
val VERY_HARD_LIMIT_TEMP_MIN_BG = intArrayOf(72, 180)
|
||||
val VERY_HARD_LIMIT_TEMP_MAX_BG = intArrayOf(72, 270)
|
||||
val VERY_HARD_LIMIT_TEMP_TARGET_BG = intArrayOf(72, 200)
|
||||
val MINDIA = doubleArrayOf(5.0, 5.0, 5.0, 5.0, 5.0)
|
||||
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)
|
||||
// Very Hard Limits Ranges
|
||||
// First value is the Lowest and second value is the Highest a Limit can define
|
||||
val VERY_HARD_LIMIT_MIN_BG = intArrayOf(72, 180)
|
||||
val VERY_HARD_LIMIT_MAX_BG = intArrayOf(90, 270)
|
||||
val VERY_HARD_LIMIT_TARGET_BG = intArrayOf(80, 200)
|
||||
|
||||
//LGS Hard limits
|
||||
//No IOB at all
|
||||
val MAXIOB_LGS = 0.0
|
||||
// Very Hard Limits Ranges for Temp Targets
|
||||
val VERY_HARD_LIMIT_TEMP_MIN_BG = intArrayOf(72, 180)
|
||||
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 {
|
||||
return MAXBOLUS[loadAge()]
|
||||
private fun loadAge(): Int = when (sp.getString(R.string.key_age, "")) {
|
||||
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 {
|
||||
return MAXIOB_AMA[loadAge()]
|
||||
}
|
||||
|
||||
fun maxIobSMB(): Double {
|
||||
return MAXIOB_SMB[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()]
|
||||
}
|
||||
fun maxBolus(): Double = MAX_BOLUS[loadAge()]
|
||||
fun maxIobAMA(): Double = MAX_IOB_AMA[loadAge()]
|
||||
fun maxIobSMB(): Double = MAX_IOB_SMB[loadAge()]
|
||||
fun maxBasal(): Double = MAX_BASAL[loadAge()]
|
||||
fun minDia(): Double = MIN_DIA[loadAge()]
|
||||
fun maxDia(): Double = MAX_DIA[loadAge()]
|
||||
fun minIC(): Double = MIN_IC[loadAge()]
|
||||
fun maxIC(): Double = MAX_IC[loadAge()]
|
||||
|
||||
// safety checks
|
||||
fun checkOnlyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean {
|
||||
return value == verifyHardLimits(value, valueName, lowLimit, highLimit)
|
||||
}
|
||||
fun checkOnlyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean =
|
||||
value == verifyHardLimits(value, valueName, lowLimit, highLimit)
|
||||
|
||||
fun verifyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Double {
|
||||
var newvalue = value
|
||||
if (newvalue < lowLimit || newvalue > highLimit) {
|
||||
newvalue = Math.max(newvalue, lowLimit)
|
||||
newvalue = Math.min(newvalue, highLimit)
|
||||
var newValue = value
|
||||
if (newValue < lowLimit || newValue > highLimit) {
|
||||
newValue = max(newValue, lowLimit)
|
||||
newValue = min(newValue, highLimit)
|
||||
var msg = String.format(resourceHelper.gs(R.string.valueoutofrange), resourceHelper.gs(valueName))
|
||||
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)
|
||||
nsUpload.uploadError(msg)
|
||||
ToastUtils.showToastInUiThread(context, rxBus, msg, R.raw.error)
|
||||
}
|
||||
return newvalue
|
||||
return newValue
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
package info.nightscout.androidaps.utils
|
||||
package info.nightscout.androidaps.utils.extensions
|
||||
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
|
||||
fun GlucoseValue.valueToUnits(units: String): Double =
|
||||
if (units == Constants.MGDL) value
|
|
@ -12,7 +12,7 @@ class TabPageAdapter(private val activity: AppCompatActivity) : FragmentStateAda
|
|||
|
||||
override fun getItemCount(): Int = visibleFragmentList.size
|
||||
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]
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
|
||||
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.valueToUnits
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
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 {
|
||||
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
|
||||
var bg = 0.0
|
||||
if (useBG() == YES) {
|
||||
|
|
|
@ -77,16 +77,19 @@
|
|||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingEnd="5dp">
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
|
@ -97,6 +100,8 @@
|
|||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="@string/time_offset"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
@ -115,11 +120,6 @@
|
|||
android:padding="2dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.MinutesNumberPicker
|
||||
android:id="@+id/time"
|
||||
android:layout_width="130dp"
|
||||
|
@ -135,80 +135,57 @@
|
|||
android:text="@string/unit_minute_short"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
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_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
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:width="120dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="@string/careportal_newnstreatment_duration_label"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold" />
|
||||
<info.nightscout.androidaps.utils.ui.NumberPicker
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="130dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
<TextView
|
||||
android:layout_width="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
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:padding="10dp"
|
||||
android:width="120dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="@string/treatments_wizard_carbs_label"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.NumberPicker
|
||||
android:id="@+id/carbs"
|
||||
|
@ -218,7 +195,6 @@
|
|||
<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"
|
||||
|
@ -226,7 +202,6 @@
|
|||
android:text="@string/shortgramm"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import info.nightscout.androidaps.TestBaseWithProfile
|
|||
import info.nightscout.androidaps.dana.DanaPump
|
||||
import info.nightscout.androidaps.danar.DanaRPlugin
|
||||
import info.nightscout.androidaps.danars.DanaRSPlugin
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
|
@ -41,6 +42,8 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
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.modules.junit4.PowerMockRunner
|
||||
import java.util.*
|
||||
|
@ -91,6 +94,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
if (it is Objective) {
|
||||
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.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.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
|
||||
`when`(sp.getString(R.string.key_danars_address, "")).thenReturn("")
|
||||
|
|
|
@ -16,7 +16,6 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
|||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.HardLimits
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.junit.Assert
|
||||
|
@ -50,15 +49,13 @@ class LoopPluginTest : TestBase() {
|
|||
@Mock lateinit var nsUpload: NSUpload
|
||||
@Mock lateinit var notificationManager: NotificationManager
|
||||
@Mock lateinit var databaseHelper: DatabaseHelperInterface
|
||||
private lateinit var hardLimits: HardLimits
|
||||
|
||||
private lateinit var loopPlugin: LoopPlugin
|
||||
|
||||
val injector = HasAndroidInjector { AndroidInjector { } }
|
||||
@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`(context.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager)
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
private lateinit var safetyPlugin: SafetyPlugin
|
||||
|
||||
val injector = HasAndroidInjector { AndroidInjector { } }
|
||||
val pumpDescription = PumpDescription()
|
||||
private val pumpDescription = PumpDescription()
|
||||
|
||||
@Before
|
||||
fun prepare() {
|
||||
|
@ -198,7 +198,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(sp.getString(R.string.key_age, "")).thenReturn("child")
|
||||
var d = Constraint(Constants.REALLYHIGHBOLUS)
|
||||
d = safetyPlugin.applyBolusConstraints(d)
|
||||
Assert.assertEquals(3.0, d.value()!!, 0.01)
|
||||
Assert.assertEquals(3.0, d.value(), 0.01)
|
||||
Assert.assertEquals("""
|
||||
Safety: Limiting bolus to 3.0 U because of max value in preferences
|
||||
Safety: Limiting bolus to 5.0 U because of hard limit
|
||||
|
@ -240,7 +240,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
// Apply all limits
|
||||
var d = Constraint(Constants.REALLYHIGHIOB)
|
||||
d = safetyPlugin.applyMaxIOBConstraints(d)
|
||||
Assert.assertEquals(1.5, d.value()!!, 0.01)
|
||||
Assert.assertEquals(1.5, d.value(), 0.01)
|
||||
Assert.assertEquals("""
|
||||
Safety: Limiting IOB to 1.5 U because of max value in preferences
|
||||
""".trimIndent(), d.getReasons(aapsLogger))
|
||||
|
|
|
@ -12,6 +12,9 @@ import org.junit.Before
|
|||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
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
|
||||
|
||||
@RunWith(PowerMockRunner::class)
|
||||
|
@ -24,6 +27,7 @@ class StorageConstraintPluginTest : TestBase() {
|
|||
|
||||
@Before fun prepareMock() {
|
||||
storageConstraintPlugin = StorageConstraintPlugin({ AndroidInjector { } }, aapsLogger, resourceHelper, rxBusWrapper)
|
||||
`when`(resourceHelper.gs(anyInt(), anyLong())).thenReturn("")
|
||||
}
|
||||
|
||||
class MockedStorageConstraintPlugin constructor(
|
||||
|
|
|
@ -83,7 +83,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
|||
var injector: HasAndroidInjector = HasAndroidInjector {
|
||||
AndroidInjector {
|
||||
if (it is PumpEnactResult) {
|
||||
it.aapsLogger = aapsLogger
|
||||
it.resourceHelper = resourceHelper
|
||||
}
|
||||
if (it is AuthRequest) {
|
||||
|
|
|
@ -8,7 +8,6 @@ import info.nightscout.androidaps.interfaces.PluginDescription
|
|||
import info.nightscout.androidaps.interfaces.SensitivityInterface
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
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.sharedPreferences.SP
|
||||
import org.json.JSONObject
|
||||
|
@ -25,7 +24,7 @@ class AbstractSensitivityPluginTest : TestBase() {
|
|||
@Mock lateinit var resourceHelper: ResourceHelper
|
||||
@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 {
|
||||
return AutosensResult()
|
||||
|
|
|
@ -8,6 +8,7 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.androidaps.TestPumpPlugin
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
|
@ -120,6 +121,7 @@ class CommandQueueTest : TestBaseWithProfile() {
|
|||
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint)
|
||||
val percentageConstraint = Constraint(0)
|
||||
`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint)
|
||||
`when`(resourceHelper.gs(R.string.connectiontimedout)).thenReturn("Connection timed out")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -41,7 +41,6 @@ class ActionAlarmTest : TestBase() {
|
|||
it.timerUtil = timerUtil
|
||||
}
|
||||
if (it is PumpEnactResult) {
|
||||
it.aapsLogger = aapsLogger
|
||||
it.resourceHelper = resourceHelper
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ class ActionNotificationTest : TestBase() {
|
|||
it.nsUpload = nsUpload
|
||||
}
|
||||
if (it is PumpEnactResult) {
|
||||
it.aapsLogger = aapsLogger
|
||||
it.resourceHelper = resourceHelper
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,7 +108,6 @@ open class ActionsTestBase : TestBaseWithProfile() {
|
|||
it.rxBus = rxBus
|
||||
}
|
||||
if (it is PumpEnactResult) {
|
||||
it.aapsLogger = aapsLogger
|
||||
it.resourceHelper = resourceHelper
|
||||
}
|
||||
if (it is InputTempTarget) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.os.SystemClock;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -166,7 +165,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
super.onStart();
|
||||
ruffyScripter = new RuffyScripter(context);
|
||||
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() {
|
||||
|
@ -252,35 +251,35 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
getAapsLogger().error("setNewBasalProfile not initialized");
|
||||
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, getResourceHelper().gs(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
|
||||
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);
|
||||
if (pump.basalProfile.equals(requestedBasalProfile)) {
|
||||
//dismiss previously "FAILED" overview notifications
|
||||
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);
|
||||
}
|
||||
|
||||
CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState);
|
||||
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,
|
||||
() -> ruffyScripter.setBasalProfile(requestedBasalProfile));
|
||||
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));
|
||||
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;
|
||||
|
||||
//dismiss previously "FAILED" overview notifications
|
||||
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
|
||||
Notification notification = new Notification(Notification.PROFILE_SET_OK, getResourceHelper().gs(R.string.profile_set_ok), Notification.INFO, 60);
|
||||
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,
|
||||
getResourceHelper().gs(R.string.combo_force_disabled_notification),
|
||||
Notification.URGENT);
|
||||
n.soundId = R.raw.alarm;
|
||||
n.setSoundId(R.raw.alarm);
|
||||
rxBus.send(new EventNewNotification(n));
|
||||
return;
|
||||
}
|
||||
|
@ -480,7 +479,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
getAapsLogger().error("deliverTreatment: Invalid input");
|
||||
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) {
|
||||
// bolus needed, ask pump to deliver it
|
||||
return deliverBolus(detailedBolusInfo);
|
||||
|
@ -496,7 +495,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
|
||||
return new PumpEnactResult(getInjector()).success(true).enacted(true)
|
||||
.bolusDelivered(0d).carbsDelivered(detailedBolusInfo.carbs)
|
||||
.comment(getResourceHelper().gs(R.string.virtualpump_resultok));
|
||||
.comment(R.string.virtualpump_resultok);
|
||||
}
|
||||
} finally {
|
||||
rxBus.send(new EventComboPumpUpdateGUI());
|
||||
|
@ -513,16 +512,16 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
CommandResult stateResult = runCommand(null, 2, () -> ruffyScripter.readQuickInfo(1));
|
||||
if (!stateResult.success) {
|
||||
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) {
|
||||
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
|
||||
if (pumpHistoryChanged) {
|
||||
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()
|
||||
|
@ -535,7 +534,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
&& previousBolus.timestamp + 60 * 1000 > System.currentTimeMillis()) {
|
||||
getAapsLogger().debug(LTag.PUMP, "Bolus request rejected, same bolus was successfully delivered very recently");
|
||||
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
|
||||
|
@ -551,7 +550,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
}
|
||||
if (!timeCheckResult.success) {
|
||||
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");
|
||||
SystemClock.sleep(2000);
|
||||
|
@ -586,7 +585,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
CommandResult postBolusStateResult = runCommand(null, 3, () -> ruffyScripter.readQuickInfo(2));
|
||||
if (!postBolusStateResult.success) {
|
||||
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()
|
||||
? postBolusStateResult.history.bolusHistory.get(0)
|
||||
|
@ -600,14 +599,14 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
return new PumpEnactResult(getInjector())
|
||||
.success(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
|
||||
if (!addBolusToTreatments(detailedBolusInfo, lastPumpBolus))
|
||||
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
|
||||
long now = System.currentTimeMillis();
|
||||
|
@ -741,14 +740,14 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
|
||||
if (pumpHistoryChanged && percent > 110) {
|
||||
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;
|
||||
|
||||
if (adjustedPercent > pumpDescription.maxTempPercent) {
|
||||
getAapsLogger().debug(LTag.PUMP, "Reducing requested TBR to the maximum support by the pump: " + percent + " -> " + pumpDescription.maxTempPercent);
|
||||
adjustedPercent = pumpDescription.maxTempPercent;
|
||||
if (adjustedPercent > pumpDescription.getMaxTempPercent()) {
|
||||
getAapsLogger().debug(LTag.PUMP, "Reducing requested TBR to the maximum support by the pump: " + percent + " -> " + pumpDescription.getMaxTempPercent());
|
||||
adjustedPercent = pumpDescription.getMaxTempPercent();
|
||||
}
|
||||
|
||||
if (adjustedPercent % 10 != 0) {
|
||||
|
@ -901,7 +900,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
Notification n = new Notification(Notification.COMBO_PUMP_ALARM,
|
||||
getResourceHelper().gs(R.string.combo_force_disabled_notification),
|
||||
Notification.URGENT);
|
||||
n.soundId = R.raw.alarm;
|
||||
n.setSoundId(R.raw.alarm);
|
||||
rxBus.send(new EventNewNotification(n));
|
||||
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
|
||||
preCheckResult = alertConfirmationResult;
|
||||
} else if (activeAlert.errorCode != null) {
|
||||
Notification notification = new Notification();
|
||||
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);
|
||||
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);
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
return preCheckResult.success(false);
|
||||
}
|
||||
|
@ -1047,15 +1042,15 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
throw new IllegalArgumentException(activeAlert.toString());
|
||||
}
|
||||
Notification notification = new Notification();
|
||||
notification.date = DateUtil.now();
|
||||
notification.id = Notification.COMBO_PUMP_ALARM;
|
||||
notification.level = Notification.NORMAL;
|
||||
notification.setDate(DateUtil.now());
|
||||
notification.setId(Notification.COMBO_PUMP_ALARM);
|
||||
notification.setLevel(Notification.NORMAL);
|
||||
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) {
|
||||
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) {
|
||||
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));
|
||||
}
|
||||
|
@ -1079,7 +1074,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
Notification n = new Notification(Notification.COMBO_PUMP_ALARM,
|
||||
getResourceHelper().gs(R.string.combo_low_suspend_forced_notification),
|
||||
Notification.URGENT);
|
||||
n.soundId = R.raw.alarm;
|
||||
n.setSoundId(R.raw.alarm);
|
||||
rxBus.send(new EventNewNotification(n));
|
||||
violationWarningRaisedForBolusAt = lowSuspendOnlyLoopEnforcedUntil;
|
||||
commandQueue.cancelTempBasal(true, null);
|
||||
|
@ -1338,8 +1333,8 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
|
|||
@NonNull @Override
|
||||
public PumpEnactResult loadTDDs() {
|
||||
PumpEnactResult result = new PumpEnactResult(getInjector());
|
||||
result.success = readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL));
|
||||
if (result.success) {
|
||||
result.success(readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL)));
|
||||
if (result.getSuccess()) {
|
||||
List<Tdd> tdds = pump.tddHistory;
|
||||
if (tdds != null) {
|
||||
HashMap<Long, TDD> map = new HashMap<>();
|
||||
|
|
|
@ -5,6 +5,7 @@ import dagger.android.AndroidInjector
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.androidaps.combo.R
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ruffyscripter.history.Bolus
|
||||
|
@ -34,6 +35,9 @@ class ComboPluginTest : TestBase() {
|
|||
|
||||
val injector = HasAndroidInjector {
|
||||
AndroidInjector {
|
||||
if (it is PumpEnactResult) {
|
||||
it.resourceHelper = resourceHelper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,6 +46,7 @@ class ComboPluginTest : TestBase() {
|
|||
@Before
|
||||
fun prepareMocks() {
|
||||
`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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
40
core/src/main/java/info/nightscout/androidaps/data/Iob.kt
Normal file
40
core/src/main/java/info/nightscout/androidaps/data/Iob.kt
Normal 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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
163
core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt
Normal file
163
core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -245,7 +245,7 @@ public class Profile {
|
|||
if (isValid) {
|
||||
// Check for hours alignment
|
||||
PumpInterface pump = activePlugin.getActivePump();
|
||||
if (!pump.getPumpDescription().is30minBasalRatesCapable) {
|
||||
if (!pump.getPumpDescription().is30minBasalRatesCapable()) {
|
||||
for (int index = 0; index < basal_v.size(); index++) {
|
||||
long secondsFromMidnight = basal_v.keyAt(index);
|
||||
if (notify && secondsFromMidnight % 3600 != 0) {
|
||||
|
@ -260,12 +260,12 @@ public class Profile {
|
|||
// Check for minimal basal value
|
||||
PumpDescription description = pump.getPumpDescription();
|
||||
for (int i = 0; i < basal_v.size(); i++) {
|
||||
if (basal_v.valueAt(i) < description.basalMinimumRate) {
|
||||
basal_v.setValueAt(i, description.basalMinimumRate);
|
||||
if (basal_v.valueAt(i) < description.getBasalMinimumRate()) {
|
||||
basal_v.setValueAt(i, description.getBasalMinimumRate());
|
||||
if (notify)
|
||||
sendBelowMinimumNotification(from);
|
||||
} else if (basal_v.valueAt(i) > description.basalMaximumRate) {
|
||||
basal_v.setValueAt(i, description.basalMaximumRate);
|
||||
} else if (basal_v.valueAt(i) > description.getBasalMaximumRate()) {
|
||||
basal_v.setValueAt(i, description.getBasalMaximumRate());
|
||||
if (notify)
|
||||
sendAboveMaximumNotification(from);
|
||||
}
|
||||
|
@ -666,14 +666,14 @@ public class Profile {
|
|||
}
|
||||
|
||||
public static String toUnitsString(double valueInMgdl, double valueInMmol, String units) {
|
||||
if (units.equals(Constants.MGDL)) return DecimalFormatter.to0Decimal(valueInMgdl);
|
||||
else return DecimalFormatter.to1Decimal(valueInMmol);
|
||||
if (units.equals(Constants.MGDL)) return DecimalFormatter.INSTANCE.to0Decimal(valueInMgdl);
|
||||
else return DecimalFormatter.INSTANCE.to1Decimal(valueInMmol);
|
||||
}
|
||||
|
||||
public static String toSignedUnitsString(double valueInMgdl, double valueInMmol, String units) {
|
||||
if (units.equals(Constants.MGDL))
|
||||
return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.to0Decimal(valueInMgdl);
|
||||
else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.to1Decimal(valueInMmol);
|
||||
return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.INSTANCE.to0Decimal(valueInMgdl);
|
||||
else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.INSTANCE.to1Decimal(valueInMmol);
|
||||
}
|
||||
|
||||
public static double toCurrentUnits(ProfileFunction profileFunction, double anyBg) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -254,8 +254,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
tempBolusPart.date = calcdate;
|
||||
|
||||
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
|
||||
result.iob += aIOB.iobContrib;
|
||||
result.activity += aIOB.activityContrib;
|
||||
result.iob += aIOB.getIobContrib();
|
||||
result.activity += aIOB.getActivityContrib();
|
||||
result.extendedBolusInsulin += tempBolusPart.insulin;
|
||||
}
|
||||
}
|
||||
|
@ -305,8 +305,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
tempBolusPart.date = calcdate;
|
||||
|
||||
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
|
||||
result.iob += aIOB.iobContrib;
|
||||
result.activity += aIOB.activityContrib;
|
||||
result.iob += aIOB.getIobContrib();
|
||||
result.activity += aIOB.getActivityContrib();
|
||||
result.extendedBolusInsulin += tempBolusPart.insulin;
|
||||
}
|
||||
}
|
||||
|
@ -330,23 +330,23 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
return "E " + DecimalFormatter.to2Decimal(absoluteRate()) + "U/h @" +
|
||||
return "E " + DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + "U/h @" +
|
||||
dateUtil.timeString(date) +
|
||||
" " + getRealDuration() + "/" + durationInMinutes + "min";
|
||||
}
|
||||
|
||||
public String toStringShort() {
|
||||
return "E " + DecimalFormatter.to2Decimal(absoluteRate()) + "U/h ";
|
||||
return "E " + DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + "U/h ";
|
||||
}
|
||||
|
||||
public String toStringMedium() {
|
||||
return DecimalFormatter.to2Decimal(absoluteRate()) + "U/h "
|
||||
return DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + "U/h "
|
||||
+ getRealDuration() + "/" + durationInMinutes + "'";
|
||||
}
|
||||
|
||||
public String toStringTotal() {
|
||||
return DecimalFormatter.to2Decimal(insulin) + "U ( " +
|
||||
DecimalFormatter.to2Decimal(absoluteRate()) + " U/h )";
|
||||
return DecimalFormatter.INSTANCE.to2Decimal(insulin) + "U ( " +
|
||||
DecimalFormatter.INSTANCE.to2Decimal(absoluteRate()) + " U/h )";
|
||||
}
|
||||
|
||||
// -------- DataPointWithLabelInterface --------
|
||||
|
|
|
@ -130,7 +130,7 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
|
|||
public String getCustomizedName() {
|
||||
String name = profileName;
|
||||
if (Constants.LOCAL_PROFILE.equals(name)) {
|
||||
name = DecimalFormatter.to2Decimal(getProfileObject().percentageBasalSum()) + "U ";
|
||||
name = DecimalFormatter.INSTANCE.to2Decimal(getProfileObject().percentageBasalSum()) + "U ";
|
||||
}
|
||||
if (isCPP) {
|
||||
name += "(" + percentage + "%";
|
||||
|
|
|
@ -285,8 +285,8 @@ public class TemporaryBasal implements Interval, DbObjectBase {
|
|||
tempBolusPart.date = calcdate;
|
||||
|
||||
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
|
||||
result.basaliob += aIOB.iobContrib;
|
||||
result.activity += aIOB.activityContrib;
|
||||
result.basaliob += aIOB.getIobContrib();
|
||||
result.activity += aIOB.getActivityContrib();
|
||||
result.netbasalinsulin += tempBolusPart.insulin;
|
||||
if (tempBolusPart.insulin > 0) {
|
||||
result.hightempinsulin += tempBolusPart.insulin;
|
||||
|
@ -352,8 +352,8 @@ public class TemporaryBasal implements Interval, DbObjectBase {
|
|||
tempBolusPart.date = calcdate;
|
||||
|
||||
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
|
||||
result.basaliob += aIOB.iobContrib;
|
||||
result.activity += aIOB.activityContrib;
|
||||
result.basaliob += aIOB.getIobContrib();
|
||||
result.activity += aIOB.getActivityContrib();
|
||||
result.netbasalinsulin += tempBolusPart.insulin;
|
||||
if (tempBolusPart.insulin > 0) {
|
||||
result.hightempinsulin += tempBolusPart.insulin;
|
||||
|
@ -431,11 +431,11 @@ public class TemporaryBasal implements Interval, DbObjectBase {
|
|||
return "null";
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
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) +
|
||||
" " + getRealDuration() + "/" + durationInMinutes + "'";
|
||||
} else if (isAbsolute) {
|
||||
return DecimalFormatter.to2Decimal(absoluteRate) + "U/h @" +
|
||||
return DecimalFormatter.INSTANCE.to2Decimal(absoluteRate) + "U/h @" +
|
||||
dateUtil.timeString(date) +
|
||||
" " + getRealDuration() + "/" + durationInMinutes + "'";
|
||||
} 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
|
||||
return percentRate + "%";
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ public class TemporaryBasal implements Interval, DbObjectBase {
|
|||
} else {
|
||||
rate = absoluteRate;
|
||||
}
|
||||
return DecimalFormatter.to2Decimal(rate) + "U/h";
|
||||
return DecimalFormatter.INSTANCE.to2Decimal(rate) + "U/h";
|
||||
} else { // percent
|
||||
return percentRate + "%";
|
||||
}
|
||||
|
|
|
@ -243,7 +243,7 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
|
|||
@Override
|
||||
public String getLabel() {
|
||||
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)
|
||||
label += "~" + resourceHelper.gs(R.string.format_carbs, (int) carbs);
|
||||
return label;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 }
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package info.nightscout.androidaps.interfaces;
|
||||
|
||||
public enum PluginType {
|
||||
GENERAL,
|
||||
TREATMENT,
|
||||
SENSITIVITY,
|
||||
PROFILE,
|
||||
APS,
|
||||
PUMP,
|
||||
CONSTRAINTS,
|
||||
LOOP,
|
||||
BGSOURCE,
|
||||
INSULIN
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.interfaces
|
||||
|
||||
enum class PluginType {
|
||||
GENERAL, TREATMENT, SENSITIVITY, PROFILE, APS, PUMP, CONSTRAINTS, LOOP, BGSOURCE, INSULIN
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
|
@ -18,6 +18,9 @@ class ConstraintChecker @Inject constructor(private val activePlugin: ActivePlug
|
|||
fun isClosedLoopAllowed(): Constraint<Boolean> =
|
||||
isClosedLoopAllowed(Constraint(true))
|
||||
|
||||
fun isLgsAllowed(): Constraint<Boolean> =
|
||||
isLgsAllowed(Constraint(true))
|
||||
|
||||
fun isAutosensModeEnabled(): Constraint<Boolean> =
|
||||
isAutosensModeEnabled(Constraint(true))
|
||||
|
||||
|
@ -77,6 +80,16 @@ class ConstraintChecker @Inject constructor(private val activePlugin: ActivePlug
|
|||
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> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(ConstraintsInterface::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
|
|
|
@ -88,7 +88,7 @@ class ProfileFunctionImplementation @Inject constructor(
|
|||
}
|
||||
if (activeTreatments.profileSwitchesFromHistory.size() > 0) {
|
||||
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.ITEM_LIST_NAME, activeTreatments.profileSwitchesFromHistory.toString())
|
||||
fabricPrivacy.logCustom(bundle)
|
||||
|
|
|
@ -25,7 +25,7 @@ class RunningConfiguration @Inject constructor(
|
|||
) {
|
||||
|
||||
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
|
||||
fun configuration(): JSONObject {
|
||||
|
@ -83,7 +83,7 @@ class RunningConfiguration @Inject constructor(
|
|||
val pumpType = JsonHelper.safeGetString(configuration, "pump", PumpType.GenericAAPS.description)
|
||||
sp.putString(R.string.key_virtualpump_type, 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"))
|
||||
|
|
|
@ -107,7 +107,7 @@ class VersionCheckerUtils @Inject constructor(
|
|||
val now = System.currentTimeMillis()
|
||||
if (now > sp.getLong(R.string.key_last_versionchecker_warning, 0) + WARN_EVERY) {
|
||||
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))
|
||||
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)
|
||||
?: ""
|
||||
|
||||
fun findVersion(file: String?): String? {
|
||||
@Suppress("unused") fun findVersion(file: String?): String? {
|
||||
val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex()
|
||||
return file?.lines()?.filter { regex.matches(it) }?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -212,7 +211,7 @@ public class NSUpload {
|
|||
|
||||
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.put("rate", lastRun.getTbrSetByPump().json(profile).get("rate"));
|
||||
deviceStatus.enacted.put("duration", lastRun.getTbrSetByPump().json(profile).get("duration"));
|
||||
|
@ -222,11 +221,11 @@ public class NSUpload {
|
|||
requested.put("temp", "absolute");
|
||||
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) {
|
||||
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());
|
||||
deviceStatus.enacted.put("requested", requested);
|
||||
}
|
||||
|
@ -240,9 +239,7 @@ public class NSUpload {
|
|||
}
|
||||
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
|
||||
JSONObject pumpstatus = pumpInterface.getJSONStatus(profile, profileName, version);
|
||||
if (pumpstatus != null) {
|
||||
deviceStatus.pump = pumpstatus;
|
||||
}
|
||||
deviceStatus.pump = pumpstatus;
|
||||
|
||||
deviceStatus.uploaderBattery = receiverStatusStore.getBatteryLevel();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ class NotificationUserMessage (text :String): Notification() {
|
|||
|
||||
init {
|
||||
var hash = text.hashCode()
|
||||
if (hash < USERMESSAGE) hash += USERMESSAGE
|
||||
if (hash < USER_MESSAGE) hash += USER_MESSAGE
|
||||
id = hash
|
||||
date = System.currentTimeMillis()
|
||||
this.text = text
|
||||
|
|
|
@ -375,7 +375,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
|
|||
ret += "LastConn: " + agoMin + " min ago\n";
|
||||
}
|
||||
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";
|
||||
}
|
||||
TemporaryBasal activeTemp = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
|
@ -392,7 +392,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
|
|||
// + pumpStatus.maxDailyTotalUnits + " 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";
|
||||
return ret;
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
|
|||
// neither carbs nor bolus requested
|
||||
aapsLogger.error("deliverTreatment: Invalid input");
|
||||
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) {
|
||||
// bolus needed, ask pump to deliver it
|
||||
return deliverBolus(detailedBolusInfo);
|
||||
|
@ -426,7 +426,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
|
|||
aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment.");
|
||||
|
||||
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 {
|
||||
triggerUIChange();
|
||||
|
@ -471,6 +471,6 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
|
|||
protected abstract void triggerUIChange();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
|
@ -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 {
|
||||
return when (this) {
|
||||
ColorGroup.InsulinTreatment -> R.color.basal
|
||||
|
|
|
@ -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) {
|
||||
editText.removeTextChangedListener(this.textWatcher);
|
||||
}
|
||||
setParams(initValue, minValue, maxValue, step, formater, allowZero, okButton);
|
||||
setParams(initValue, minValue, maxValue, step, formatter, allowZero, okButton);
|
||||
this.textWatcher = textWatcher;
|
||||
if (textWatcher != null)
|
||||
editText.addTextChangedListener(textWatcher);
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
|
||||
<!-- BlePreCheck-->
|
||||
<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="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>
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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) {}
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
package info.nightscout.androidaps.interfaces
|
||||
package info.nightscout.androidaps.data
|
||||
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
||||
|
@ -16,7 +14,7 @@ import org.powermock.modules.junit4.PowerMockRunner
|
|||
* Created by mike on 19.03.2018.
|
||||
*/
|
||||
@RunWith(PowerMockRunner::class)
|
||||
@PrepareForTest(MainApp::class, SP::class)
|
||||
@PrepareForTest(SP::class)
|
||||
class ConstraintTest : TestBase() {
|
||||
|
||||
@Test fun doTests() {
|
|
@ -23,6 +23,7 @@ class IobTest {
|
|||
Assert.assertTrue(a1 == a1)
|
||||
Assert.assertTrue(a1 == a2)
|
||||
Assert.assertFalse(a1 == b)
|
||||
@Suppress("SENSELESS_COMPARISON")
|
||||
Assert.assertFalse(a1 == null)
|
||||
Assert.assertFalse(a1 == Any())
|
||||
}
|
|
@ -6,11 +6,12 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@RunWith(PowerMockRunner::class)
|
||||
class IobTotalTest {
|
||||
|
||||
var now = DateUtil.now()
|
||||
@Test fun copytest() {
|
||||
@Test fun copyTest() {
|
||||
val a = IobTotal(now)
|
||||
a.iob = 10.0
|
||||
val b = a.copy()
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue