APSResult interface

This commit is contained in:
Milos Kozak 2022-11-11 21:12:49 +01:00
parent 4e939e0c8c
commit 4da9f529c2
18 changed files with 146 additions and 106 deletions

View file

@ -31,7 +31,6 @@ import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotifi
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.extensions.buildDeviceStatus
import info.nightscout.core.fabric.FabricPrivacy import info.nightscout.core.fabric.FabricPrivacy
import info.nightscout.database.entities.OfflineEvent import info.nightscout.database.entities.OfflineEvent
import info.nightscout.database.entities.UserEntry.Action import info.nightscout.database.entities.UserEntry.Action
@ -43,6 +42,7 @@ import info.nightscout.database.impl.transactions.InsertAndCancelCurrentOfflineE
import info.nightscout.database.impl.transactions.InsertTherapyEventAnnouncementTransaction import info.nightscout.database.impl.transactions.InsertTherapyEventAnnouncementTransaction
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.notifications.Notification import info.nightscout.interfaces.notifications.Notification
@ -60,6 +60,7 @@ import info.nightscout.interfaces.ui.ActivityNames
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.configBuilder.RunningConfiguration import info.nightscout.plugins.configBuilder.RunningConfiguration
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.plugins.sync.nsclient.extensions.buildDeviceStatus
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventAcceptOpenLoopChange import info.nightscout.rx.events.EventAcceptOpenLoopChange
@ -384,8 +385,9 @@ class LoopPlugin @Inject constructor(
) { ) {
val waiting = PumpEnactResultObject(injector) val waiting = PumpEnactResultObject(injector)
waiting.queued = true waiting.queued = true
if (resultAfterConstraints.tempBasalRequested) lastRun.tbrSetByPump = waiting if (resultAfterConstraints.isTempBasalRequested) lastRun.tbrSetByPump = waiting
if (resultAfterConstraints.bolusRequested()) lastRun.smbSetByPump = waiting if (resultAfterConstraints.isBolusRequested) lastRun.smbSetByPump =
waiting
rxBus.send(EventLoopUpdateGui()) rxBus.send(EventLoopUpdateGui())
fabricPrivacy.logCustom("APSRequest") fabricPrivacy.logCustom("APSRequest")
// TBR request must be applied first to prevent situation where // TBR request must be applied first to prevent situation where
@ -532,7 +534,7 @@ class LoopPlugin @Inject constructor(
* TODO: update pump drivers to support APS request in % * TODO: update pump drivers to support APS request in %
*/ */
private fun applyTBRRequest(request: APSResult, profile: Profile, callback: Callback?) { private fun applyTBRRequest(request: APSResult, profile: Profile, callback: Callback?) {
if (!request.tempBasalRequested) { if (!request.isTempBasalRequested) {
callback?.result(PumpEnactResultObject(injector).enacted(false).success(true).comment(R.string.nochangerequested))?.run() callback?.result(PumpEnactResultObject(injector).enacted(false).success(true).comment(R.string.nochangerequested))?.run()
return return
} }
@ -622,7 +624,7 @@ class LoopPlugin @Inject constructor(
} }
private fun applySMBRequest(request: APSResult, callback: Callback?) { private fun applySMBRequest(request: APSResult, callback: Callback?) {
if (!request.bolusRequested()) { if (!request.isBolusRequested) {
aapsLogger.debug(LTag.APS, "No SMB requested") aapsLogger.debug(LTag.APS, "No SMB requested")
return return
} }

View file

@ -8,7 +8,7 @@ import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResultObject
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
@ -64,7 +64,7 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
override var scriptDebug = "" override var scriptDebug = ""
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
override operator fun invoke(): APSResult? { override operator fun invoke(): APSResultObject? {
aapsLogger.debug(LTag.APS, ">>> Invoking determine_basal <<<") aapsLogger.debug(LTag.APS, ">>> Invoking determine_basal <<<")
aapsLogger.debug(LTag.APS, "Glucose status: " + glucoseStatus.toString().also { glucoseStatusParam = it }) aapsLogger.debug(LTag.APS, "Glucose status: " + glucoseStatus.toString().also { glucoseStatusParam = it })
aapsLogger.debug(LTag.APS, "IOB data: " + iobData.toString().also { iobDataParam = it }) aapsLogger.debug(LTag.APS, "IOB data: " + iobData.toString().also { iobDataParam = it })

View file

@ -1,13 +1,13 @@
package info.nightscout.androidaps.plugins.aps.openAPSAMA package info.nightscout.androidaps.plugins.aps.openAPSAMA
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResultObject
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
class DetermineBasalResultAMA private constructor(injector: HasAndroidInjector) : APSResult(injector) { class DetermineBasalResultAMA private constructor(injector: HasAndroidInjector) : APSResultObject(injector) {
private var eventualBG = 0.0 private var eventualBG = 0.0
private var snoozeBG = 0.0 private var snoozeBG = 0.0
@ -17,7 +17,7 @@ class DetermineBasalResultAMA private constructor(injector: HasAndroidInjector)
json = j json = j
if (result.containsKey("error")) { if (result.containsKey("error")) {
reason = result["error"].toString() reason = result["error"].toString()
tempBasalRequested = false isTempBasalRequested = false
rate = (-1).toDouble() rate = (-1).toDouble()
duration = -1 duration = -1
} else { } else {
@ -27,17 +27,17 @@ class DetermineBasalResultAMA private constructor(injector: HasAndroidInjector)
if (result.containsKey("rate")) { if (result.containsKey("rate")) {
rate = result["rate"] as Double rate = result["rate"] as Double
if (rate < 0.0) rate = 0.0 if (rate < 0.0) rate = 0.0
tempBasalRequested = true isTempBasalRequested = true
} else { } else {
rate = (-1).toDouble() rate = (-1).toDouble()
tempBasalRequested = false isTempBasalRequested = false
} }
if (result.containsKey("duration")) { if (result.containsKey("duration")) {
duration = (result["duration"] as Double).toInt() duration = (result["duration"] as Double).toInt()
//changeRequested as above //changeRequested as above
} else { } else {
duration = -1 duration = -1
tempBasalRequested = false isTempBasalRequested = false
} }
} }
} }

View file

@ -195,7 +195,7 @@ class OpenAPSAMAPlugin @Inject constructor(
lastAPSResult = null lastAPSResult = null
lastAPSRun = 0 lastAPSRun = 0
} else { } else {
if (determineBasalResultAMA.rate == 0.0 && determineBasalResultAMA.duration == 0 && iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now()) == null) determineBasalResultAMA.tempBasalRequested = if (determineBasalResultAMA.rate == 0.0 && determineBasalResultAMA.duration == 0 && iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now()) == null) determineBasalResultAMA.isTempBasalRequested =
false false
determineBasalResultAMA.iob = iobArray[0] determineBasalResultAMA.iob = iobArray[0]
val now = System.currentTimeMillis() val now = System.currentTimeMillis()

View file

@ -9,7 +9,7 @@ import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResultObject
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
@ -69,7 +69,7 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
override var scriptDebug = "" override var scriptDebug = ""
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
override operator fun invoke(): APSResult? { override operator fun invoke(): APSResultObject? {
aapsLogger.debug(LTag.APS, ">>> Invoking determine_basal <<<") aapsLogger.debug(LTag.APS, ">>> Invoking determine_basal <<<")
aapsLogger.debug(LTag.APS, "Glucose status: " + mGlucoseStatus.toString().also { glucoseStatusParam = it }) aapsLogger.debug(LTag.APS, "Glucose status: " + mGlucoseStatus.toString().also { glucoseStatusParam = it })
aapsLogger.debug(LTag.APS, "IOB data: " + iobData.toString().also { iobDataParam = it }) aapsLogger.debug(LTag.APS, "IOB data: " + iobData.toString().also { iobDataParam = it })

View file

@ -1,13 +1,13 @@
package info.nightscout.androidaps.plugins.aps.openAPSSMB package info.nightscout.androidaps.plugins.aps.openAPSSMB
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResultObject
import info.nightscout.interfaces.aps.VariableSensitivityResult import info.nightscout.interfaces.aps.VariableSensitivityResult
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector) : APSResult(injector), VariableSensitivityResult { class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector) : APSResultObject(injector), VariableSensitivityResult {
private var eventualBG = 0.0 private var eventualBG = 0.0
private var snoozeBG = 0.0 private var snoozeBG = 0.0
@ -28,7 +28,7 @@ class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector)
if (result.has("carbsReq")) carbsReq = result.getInt("carbsReq") if (result.has("carbsReq")) carbsReq = result.getInt("carbsReq")
if (result.has("carbsReqWithin")) carbsReqWithin = result.getInt("carbsReqWithin") if (result.has("carbsReqWithin")) carbsReqWithin = result.getInt("carbsReqWithin")
if (result.has("rate") && result.has("duration")) { if (result.has("rate") && result.has("duration")) {
tempBasalRequested = true isTempBasalRequested = true
rate = result.getDouble("rate") rate = result.getDouble("rate")
if (rate < 0.0) rate = 0.0 if (rate < 0.0) rate = 0.0
duration = result.getInt("duration") duration = result.getInt("duration")

View file

@ -222,7 +222,7 @@ class OpenAPSSMBPlugin @Inject constructor(
} else { } else {
// TODO still needed with oref1? // TODO still needed with oref1?
// Fix bug determine basal // Fix bug determine basal
if (determineBasalResultSMB.rate == 0.0 && determineBasalResultSMB.duration == 0 && iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now()) == null) determineBasalResultSMB.tempBasalRequested = if (determineBasalResultSMB.rate == 0.0 && determineBasalResultSMB.duration == 0 && iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now()) == null) determineBasalResultSMB.isTempBasalRequested =
false false
determineBasalResultSMB.iob = iobArray[0] determineBasalResultSMB.iob = iobArray[0]
determineBasalResultSMB.json?.put("timestamp", dateUtil.toISOString(now)) determineBasalResultSMB.json?.put("timestamp", dateUtil.toISOString(now))

View file

@ -19,7 +19,6 @@ import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.Loop
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
import info.nightscout.androidaps.utils.extensions.buildDeviceStatus
import info.nightscout.core.fabric.FabricPrivacy import info.nightscout.core.fabric.FabricPrivacy
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
@ -29,6 +28,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.queue.Command import info.nightscout.interfaces.queue.Command
import info.nightscout.interfaces.queue.CommandQueue import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.plugins.configBuilder.RunningConfiguration import info.nightscout.plugins.configBuilder.RunningConfiguration
import info.nightscout.plugins.sync.nsclient.extensions.buildDeviceStatus
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventProfileSwitchChanged import info.nightscout.rx.events.EventProfileSwitchChanged
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.di
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.data.PumpEnactResultObject import info.nightscout.androidaps.data.PumpEnactResultObject
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResultObject
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
import info.nightscout.core.profile.ProfileStoreObject import info.nightscout.core.profile.ProfileStoreObject
@ -12,7 +12,7 @@ import info.nightscout.core.profile.ProfileStoreObject
abstract class CoreDataClassesModule { abstract class CoreDataClassesModule {
@ContributesAndroidInjector abstract fun pumpEnactResultInjector(): PumpEnactResultObject @ContributesAndroidInjector abstract fun pumpEnactResultInjector(): PumpEnactResultObject
@ContributesAndroidInjector abstract fun apsResultInjector(): APSResult @ContributesAndroidInjector abstract fun apsResultInjector(): APSResultObject
@ContributesAndroidInjector abstract fun autosensDataInjector(): AutosensData @ContributesAndroidInjector abstract fun autosensDataInjector(): AutosensData
@ContributesAndroidInjector abstract fun profileStoreInjector(): ProfileStoreObject @ContributesAndroidInjector abstract fun profileStoreInjector(): ProfileStoreObject

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.plugins.aps.loop.APSResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.interfaces.aps.APSResult
interface APS { interface APS {

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResultObject
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.interfaces.iob.IobTotal import info.nightscout.interfaces.iob.IobTotal
import info.nightscout.interfaces.iob.MealData import info.nightscout.interfaces.iob.MealData
@ -33,5 +33,5 @@ interface DetermineBasalAdapterInterface {
isSaveCgmSource: Boolean = false isSaveCgmSource: Boolean = false
) )
operator fun invoke(): APSResult? operator fun invoke(): APSResultObject?
} }

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.plugins.aps.loop.APSResult
import info.nightscout.database.entities.OfflineEvent import info.nightscout.database.entities.OfflineEvent
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.profile.Profile import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.pump.PumpEnactResult import info.nightscout.interfaces.pump.PumpEnactResult

View file

@ -9,6 +9,7 @@ import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.core.main.R import info.nightscout.core.main.R
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.IobTotal import info.nightscout.interfaces.iob.IobTotal
@ -30,7 +31,7 @@ import kotlin.math.max
* Created by mike on 09.06.2016. * Created by mike on 09.06.2016.
*/ */
@Suppress("LeakingThis") @Suppress("LeakingThis")
open class APSResult @Inject constructor(val injector: HasAndroidInjector) { open class APSResultObject @Inject constructor(val injector: HasAndroidInjector) : APSResult {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var constraintChecker: Constraints @Inject lateinit var constraintChecker: Constraints
@ -42,60 +43,30 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
var date: Long = 0 var date: Long = 0
var reason: String = "" override var reason: String = ""
var rate = 0.0 override var rate = 0.0
var percent = 0 override var percent = 0
var usePercent = false override var usePercent = false
var duration = 0 override var duration = 0
var tempBasalRequested = false override var isTempBasalRequested = false
var iob: IobTotal? = null override var iob: IobTotal? = null
var json: JSONObject? = JSONObject() override var json: JSONObject? = JSONObject()
var hasPredictions = false override var hasPredictions = false
var smb = 0.0 // super micro bolus in units override var smb = 0.0 // super micro bolus in units
var deliverAt: Long = 0 override var deliverAt: Long = 0
var targetBG = 0.0 override var targetBG = 0.0
var carbsReq = 0 override var carbsReq = 0
var carbsReqWithin = 0 override var carbsReqWithin = 0
var inputConstraints: Constraint<Double>? = null override var inputConstraints: Constraint<Double>? = null
var rateConstraint: Constraint<Double>? = null override var rateConstraint: Constraint<Double>? = null
var percentConstraint: Constraint<Int>? = null override var percentConstraint: Constraint<Int>? = null
var smbConstraint: Constraint<Double>? = null override var smbConstraint: Constraint<Double>? = null
init { init {
injector.androidInjector().inject(this) injector.androidInjector().inject(this)
} }
fun rate(rate: Double): APSResult { override val carbsRequiredText: String
this.rate = rate
return this
}
fun duration(duration: Int): APSResult {
this.duration = duration
return this
}
fun percent(percent: Int): APSResult {
this.percent = percent
return this
}
fun tempBasalRequested(tempBasalRequested: Boolean): APSResult {
this.tempBasalRequested = tempBasalRequested
return this
}
fun usePercent(usePercent: Boolean): APSResult {
this.usePercent = usePercent
return this
}
fun json(json: JSONObject?): APSResult {
this.json = json
return this
}
val carbsRequiredText: String
get() = rh.gs(R.string.carbsreq, carbsReq, carbsReqWithin) get() = rh.gs(R.string.carbsreq, carbsReq, carbsReqWithin)
override fun toString(): String { override fun toString(): String {
@ -123,15 +94,20 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
} else rh.gs(R.string.nochangerequested) } else rh.gs(R.string.nochangerequested)
} }
fun toSpanned(): Spanned { override fun toSpanned(): Spanned {
val pump = activePlugin.activePump val pump = activePlugin.activePump
if (isChangeRequested) { if (isChangeRequested) {
// rate // rate
var ret: String = if (rate == 0.0 && duration == 0) rh.gs(R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(percent.toDouble()) + "% " + var ret: String =
"(" + DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" + if (rate == 0.0 && duration == 0) rh.gs(R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(
"<b>" + rh.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " + percent.toDouble()
"(" + DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" + ) + "% " +
"<b>" + rh.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" "(" + DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
"<b>" + rh.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(
rate
) + " U/h " +
"(" + DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
"<b>" + rh.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
// smb // smb
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, rh) + "<br>" if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, rh) + "<br>"
@ -148,18 +124,18 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
} else fromHtml(rh.gs(R.string.nochangerequested)) } else fromHtml(rh.gs(R.string.nochangerequested))
} }
open fun newAndClone(injector: HasAndroidInjector): APSResult { override fun newAndClone(injector: HasAndroidInjector): APSResult {
val newResult = APSResult(injector) val newResult = APSResultObject(injector)
doClone(newResult) doClone(newResult)
return newResult return newResult
} }
protected fun doClone(newResult: APSResult) { protected fun doClone(newResult: APSResultObject) {
newResult.date = date newResult.date = date
newResult.reason = reason newResult.reason = reason
newResult.rate = rate newResult.rate = rate
newResult.duration = duration newResult.duration = duration
newResult.tempBasalRequested = tempBasalRequested newResult.isTempBasalRequested = isTempBasalRequested
newResult.iob = iob newResult.iob = iob
newResult.json = JSONObject(json.toString()) newResult.json = JSONObject(json.toString())
newResult.hasPredictions = hasPredictions newResult.hasPredictions = hasPredictions
@ -174,7 +150,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
newResult.targetBG = targetBG newResult.targetBG = targetBG
} }
open fun json(): JSONObject? { override fun json(): JSONObject? {
val json = JSONObject() val json = JSONObject()
if (isChangeRequested) { if (isChangeRequested) {
json.put("rate", rate) json.put("rate", rate)
@ -184,7 +160,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
return json return json
} }
val predictions: MutableList<GlucoseValue> override val predictions: MutableList<GlucoseValue>
get() { get() {
val array: MutableList<GlucoseValue> = ArrayList() val array: MutableList<GlucoseValue> = ArrayList()
val startTime = date val startTime = date
@ -265,7 +241,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
} }
return array return array
} }
val latestPredictionsTime: Long override val latestPredictionsTime: Long
get() { get() {
var latest: Long = 0 var latest: Long = 0
try { try {
@ -298,20 +274,17 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
} }
return latest return latest
} }
val isCarbsRequired: Boolean override val isChangeRequested: Boolean
get() = carbsReq > 0
val isChangeRequested: Boolean
get() { get() {
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed() val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
// closed loop mode: handle change at driver level // closed loop mode: handle change at driver level
if (closedLoopEnabled.value()) { if (closedLoopEnabled.value()) {
aapsLogger.debug(LTag.APS, "DEFAULT: Closed mode") aapsLogger.debug(LTag.APS, "DEFAULT: Closed mode")
return tempBasalRequested || bolusRequested() return isTempBasalRequested || isBolusRequested
} }
// open loop mode: try to limit request // open loop mode: try to limit request
if (!tempBasalRequested && !bolusRequested()) { if (!isTempBasalRequested && !isBolusRequested) {
aapsLogger.debug(LTag.APS, "FALSE: No request") aapsLogger.debug(LTag.APS, "FALSE: No request")
return false return false
} }
@ -397,6 +370,4 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
} }
} }
} }
fun bolusRequested(): Boolean = smb > 0.0
} }

View file

@ -5,6 +5,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.database.entities.TemporaryBasal import info.nightscout.database.entities.TemporaryBasal
import info.nightscout.interfaces.aps.APSResult
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.pump.defs.PumpType import info.nightscout.interfaces.pump.defs.PumpType
@ -25,10 +26,35 @@ class APSResultTest : TestBaseWithProfile() {
private var closedLoopEnabled = Constraint(false) private var closedLoopEnabled = Constraint(false)
private fun APSResult.percent(percent: Int): APSResult {
this.percent = percent
return this
}
private fun APSResult.rate(rate: Double): APSResult {
this.rate = rate
return this
}
private fun APSResult.duration(duration: Int): APSResult {
this.duration = duration
return this
}
private fun APSResult.usePercent(usePercent: Boolean): APSResult {
this.usePercent = usePercent
return this
}
private fun APSResult.tempBasalRequested(tempBasalRequested: Boolean): APSResult {
this.isTempBasalRequested = tempBasalRequested
return this
}
@Test @Test
fun changeRequestedTest() { fun changeRequestedTest() {
val apsResult = APSResult { AndroidInjector { } } val apsResult = APSResultObject { AndroidInjector { } }
.also { .also {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger
it.constraintChecker = constraints it.constraintChecker = constraints
@ -269,7 +295,7 @@ class APSResultTest : TestBaseWithProfile() {
} }
@Test fun cloneTest() { @Test fun cloneTest() {
val apsResult = APSResult { AndroidInjector { } } val apsResult = APSResultObject { AndroidInjector { } }
.also { .also {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger
it.constraintChecker = constraints it.constraintChecker = constraints
@ -286,7 +312,7 @@ class APSResultTest : TestBaseWithProfile() {
@Test fun jsonTest() { @Test fun jsonTest() {
closedLoopEnabled.set(aapsLogger, true) closedLoopEnabled.set(aapsLogger, true)
val apsResult = APSResult { AndroidInjector { } } val apsResult = APSResultObject { AndroidInjector { } }
.also { .also {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger
it.constraintChecker = constraints it.constraintChecker = constraints

View file

@ -0,0 +1,42 @@
package info.nightscout.interfaces.aps
import android.text.Spanned
import dagger.android.HasAndroidInjector
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.iob.IobTotal
import org.json.JSONObject
interface APSResult {
var json: JSONObject?
var reason: String
var rate: Double
var percent: Int
var duration: Int
var smb: Double
var iob: IobTotal?
var usePercent: Boolean
var carbsReq: Int
var carbsReqWithin: Int
var deliverAt: Long
var targetBG: Double
var hasPredictions: Boolean
val predictions: MutableList<GlucoseValue>
val latestPredictionsTime: Long
val isChangeRequested: Boolean
var isTempBasalRequested: Boolean
val isCarbsRequired: Boolean get() = carbsReq > 0
val isBolusRequested: Boolean get() = smb > 0.0
val carbsRequiredText: String
var inputConstraints: Constraint<Double>?
var rateConstraint: Constraint<Double>?
var percentConstraint: Constraint<Int>?
var smbConstraint: Constraint<Double>?
fun toSpanned(): Spanned
fun newAndClone(injector: HasAndroidInjector): APSResult
fun json(): JSONObject?
}

View file

@ -2,7 +2,6 @@ package info.nightscout.plugins.sync.nsclient
import info.nightscout.androidaps.extensions.toJson import info.nightscout.androidaps.extensions.toJson
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.utils.extensions.toJson
import info.nightscout.database.entities.Bolus import info.nightscout.database.entities.Bolus
import info.nightscout.database.entities.BolusCalculatorResult import info.nightscout.database.entities.BolusCalculatorResult
import info.nightscout.database.entities.Carbs import info.nightscout.database.entities.Carbs

View file

@ -2,7 +2,7 @@ package info.nightscout.plugins.sync.nsclient.data
import android.text.Spanned import android.text.Spanned
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResultObject
import info.nightscout.interfaces.utils.HtmlHelper import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.Round import info.nightscout.interfaces.utils.Round
@ -158,8 +158,8 @@ class ProcessedDeviceStatusData @Inject constructor(
val openApsTimestamp: Long val openApsTimestamp: Long
get() = if (openAPSData.clockSuggested != 0L) openAPSData.clockSuggested else -1 get() = if (openAPSData.clockSuggested != 0L) openAPSData.clockSuggested else -1
fun getAPSResult(injector: HasAndroidInjector): APSResult { fun getAPSResult(injector: HasAndroidInjector): APSResultObject {
val result = APSResult(injector) val result = APSResultObject(injector)
result.json = openAPSData.suggested result.json = openAPSData.suggested
result.date = openAPSData.clockSuggested result.date = openAPSData.clockSuggested
return result return result

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.utils.extensions package info.nightscout.plugins.sync.nsclient.extensions
import android.os.Build import android.os.Build
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator