Merge branch 'dev' of https://github.com/nightscout/AndroidAPS into avereha/warnings

This commit is contained in:
Andrei Vereha 2021-10-03 21:01:50 +02:00
commit a4a6f45372
9 changed files with 91 additions and 78 deletions

View file

@ -11,6 +11,7 @@ import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.PluginStore import info.nightscout.androidaps.plugins.configBuilder.PluginStore
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
@ -22,6 +23,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorP
import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation
import info.nightscout.androidaps.queue.CommandQueue import info.nightscout.androidaps.queue.CommandQueue
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
@ -69,8 +71,15 @@ open class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideProfileFunction(aapsLogger: AAPSLogger, sp: SP, resourceHelper: ResourceHelper, activePlugin: ActivePlugin, repository: AppRepository, dateUtil: DateUtil): ProfileFunction = fun provideProfileFunction(
ProfileFunctionImplementation(aapsLogger, sp, resourceHelper, activePlugin, repository, dateUtil) aapsLogger: AAPSLogger, sp: SP, rxBus: RxBusWrapper, resourceHelper:
ResourceHelper, activePlugin:
ActivePlugin, repository: AppRepository, dateUtil: DateUtil, config: Config, hardLimits: HardLimits
): ProfileFunction =
ProfileFunctionImplementation(
aapsLogger, sp, rxBus, resourceHelper, activePlugin, repository, dateUtil,
config, hardLimits
)
@Module @Module
interface AppBindings { interface AppBindings {

View file

@ -9,14 +9,12 @@ import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.ProfileSwitch import info.nightscout.androidaps.database.entities.ProfileSwitch
import info.nightscout.androidaps.database.transactions.InsertOrUpdateProfileSwitch import info.nightscout.androidaps.database.transactions.InsertOrUpdateProfileSwitch
import info.nightscout.androidaps.extensions.fromConstant import info.nightscout.androidaps.extensions.fromConstant
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -30,10 +28,13 @@ import javax.inject.Singleton
class ProfileFunctionImplementation @Inject constructor( class ProfileFunctionImplementation @Inject constructor(
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val sp: SP, private val sp: SP,
private val rxBus: RxBusWrapper,
private val resourceHelper: ResourceHelper, private val resourceHelper: ResourceHelper,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val repository: AppRepository, private val repository: AppRepository,
private val dateUtil: DateUtil private val dateUtil: DateUtil,
private val config: Config,
private val hardLimits: HardLimits
) : ProfileFunction { ) : ProfileFunction {
val cache = LongSparseArray<Profile>() val cache = LongSparseArray<Profile>()
@ -115,35 +116,39 @@ class ProfileFunctionImplementation @Inject constructor(
val ps = buildProfileSwitch(profileStore, profileName, durationInMinutes, percentage, timeShiftInHours, timestamp) val ps = buildProfileSwitch(profileStore, profileName, durationInMinutes, percentage, timeShiftInHours, timestamp)
disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps)) disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps))
.subscribe({ result -> .subscribe({ result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") } result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") }
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated ProfileSwitch $it") } result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated ProfileSwitch $it") }
}, { }, {
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it) aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
}) })
} }
override fun createProfileSwitch(durationInMinutes: Int, percentage: Int, timeShiftInHours: Int) { override fun createProfileSwitch(durationInMinutes: Int, percentage: Int, timeShiftInHours: Int): Boolean {
val profile = repository.getPermanentProfileSwitch(dateUtil.now()) val profile = repository.getPermanentProfileSwitch(dateUtil.now())
?: throw InvalidParameterSpecException("No active ProfileSwitch") ?: throw InvalidParameterSpecException("No active ProfileSwitch")
val ps = ProfileSwitch( val profileStore = activePlugin.activeProfileSource.profile ?: return false
timestamp = dateUtil.now(), val ps = buildProfileSwitch(profileStore, profile.profileName, durationInMinutes, percentage, 0, dateUtil.now())
basalBlocks = profile.basalBlocks, val validity = ProfileSealed.PS(ps).isValid(
isfBlocks = profile.isfBlocks, resourceHelper.gs(info.nightscout.androidaps.automation.R.string.careportal_profileswitch),
icBlocks = profile.icBlocks, activePlugin.activePump,
targetBlocks = profile.targetBlocks, config,
glucoseUnit = profile.glucoseUnit, resourceHelper,
profileName = profile.profileName, rxBus,
timeshift = T.hours(timeShiftInHours.toLong()).msecs(), hardLimits
percentage = percentage,
duration = T.mins(durationInMinutes.toLong()).msecs(),
insulinConfiguration = activePlugin.activeInsulin.insulinConfiguration
) )
disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps)) var returnValue = true
.subscribe({ result -> if (validity.isValid) {
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") } repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps))
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated ProfileSwitch $it") } .doOnError {
}, { aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it) returnValue = false
}) }
.blockingGet()
.also { result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") }
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated ProfileSwitch $it") }
}
} else returnValue = false
return returnValue
} }
} }

View file

@ -72,9 +72,6 @@ class OverviewData @Inject constructor(
var endTime: Long = 0 var endTime: Long = 0
fun reset() { fun reset() {
profile = null
profileName = null
profileNameWithRemainingTime = null
calcProgress = "" calcProgress = ""
lastBg = null lastBg = null
temporaryBasal = null temporaryBasal = null
@ -125,27 +122,6 @@ class OverviewData @Inject constructor(
endTime = toTime endTime = toTime
} }
/*
* PROFILE
*/
var profile: Profile? = null
var profileName: String? = null
var profileNameWithRemainingTime: String? = null
val profileBackgroundColor: Int
get() =
profile?.let { profile ->
if (profile.percentage != 100 || profile.timeshift != 0) resourceHelper.gc(R.color.ribbonWarning)
else resourceHelper.gc(R.color.ribbonDefault)
} ?: resourceHelper.gc(R.color.ribbonTextDefault)
val profileTextColor: Int
get() =
profile?.let { profile ->
if (profile.percentage != 100 || profile.timeshift != 0) resourceHelper.gc(R.color.ribbonTextWarning)
else resourceHelper.gc(R.color.ribbonTextDefault)
} ?: resourceHelper.gc(R.color.ribbonTextDefault)
/* /*
* CALC PROGRESS * CALC PROGRESS
*/ */
@ -181,14 +157,14 @@ class OverviewData @Inject constructor(
val temporaryBasalText: String val temporaryBasalText: String
get() = get() =
profile?.let { profile -> profileFunction.getProfile()?.let { profile ->
if (temporaryBasal?.isInProgress == false) temporaryBasal = null if (temporaryBasal?.isInProgress == false) temporaryBasal = null
temporaryBasal?.let { "T:" + it.toStringShort() } temporaryBasal?.let { "T:" + it.toStringShort() }
?: resourceHelper.gs(R.string.pump_basebasalrate, profile.getBasal()) ?: resourceHelper.gs(R.string.pump_basebasalrate, profile.getBasal())
} ?: resourceHelper.gs(R.string.notavailable) } ?: resourceHelper.gs(R.string.notavailable)
val temporaryBasalDialogText: String val temporaryBasalDialogText: String
get() = profile?.let { profile -> get() = profileFunction.getProfile()?.let { profile ->
temporaryBasal?.let { temporaryBasal -> temporaryBasal?.let { temporaryBasal ->
"${resourceHelper.gs(R.string.basebasalrate_label)}: ${resourceHelper.gs(R.string.pump_basebasalrate, profile.getBasal())}" + "${resourceHelper.gs(R.string.basebasalrate_label)}: ${resourceHelper.gs(R.string.pump_basebasalrate, profile.getBasal())}" +
"\n" + resourceHelper.gs(R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil) "\n" + resourceHelper.gs(R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil)
@ -198,7 +174,7 @@ class OverviewData @Inject constructor(
val temporaryBasalIcon: Int val temporaryBasalIcon: Int
get() = get() =
profile?.let { profile -> profileFunction.getProfile()?.let { profile ->
temporaryBasal?.let { temporaryBasal -> temporaryBasal?.let { temporaryBasal ->
val percentRate = temporaryBasal.convertedToPercent(dateUtil.now(), profile) val percentRate = temporaryBasal.convertedToPercent(dateUtil.now(), profile)
when { when {
@ -510,7 +486,7 @@ class OverviewData @Inject constructor(
@Synchronized @Synchronized
fun prepareTemporaryTargetData(from: String) { fun prepareTemporaryTargetData(from: String) {
// val start = dateUtil.now() // val start = dateUtil.now()
val profile = profile ?: return val profile = profileFunction.getProfile() ?: return
val units = profileFunction.getUnits() val units = profileFunction.getUnits()
var toTime = toTime var toTime = toTime
val targetsSeriesArray: MutableList<DataPoint> = java.util.ArrayList() val targetsSeriesArray: MutableList<DataPoint> = java.util.ArrayList()

View file

@ -26,6 +26,7 @@ import dagger.android.HasAndroidInjector
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.UserEntry.Sources
@ -598,7 +599,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
fun updateGUI(from: String, what: OverviewData.Property) { fun updateGUI(from: String, what: OverviewData.Property) {
// if (what != OverviewData.Property.CALC_PROGRESS) // if (what != OverviewData.Property.CALC_PROGRESS)
// aapsLogger.debug(LTag.UI, "UpdateGui $from $what") // aapsLogger.debug(LTag.UI, "UpdateGui $from $what")
if (overviewData.profile == null) { if (profileFunction.getProfile() == null) {
binding.loopPumpStatusLayout.pumpStatus.setText(R.string.noprofileset) binding.loopPumpStatusLayout.pumpStatus.setText(R.string.noprofileset)
binding.loopPumpStatusLayout.pumpStatusLayout.visibility = View.VISIBLE binding.loopPumpStatusLayout.pumpStatusLayout.visibility = View.VISIBLE
binding.loopPumpStatusLayout.loopLayout.visibility = View.GONE binding.loopPumpStatusLayout.loopLayout.visibility = View.GONE
@ -641,10 +642,25 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
} }
OverviewData.Property.PROFILE -> { OverviewData.Property.PROFILE -> {
binding.loopPumpStatusLayout.activeProfile.text = overviewData.profileNameWithRemainingTime val profileBackgroundColor =
?: "" profileFunction.getProfile()?.let {
binding.loopPumpStatusLayout.activeProfile.setBackgroundColor(overviewData.profileBackgroundColor) val profile = (it as ProfileSealed.EPS).value
binding.loopPumpStatusLayout.activeProfile.setTextColor(overviewData.profileTextColor) if (profile.originalPercentage != 100 || profile.originalTimeshift != 0L || profile.originalDuration != 0L)
resourceHelper.gc(R.color.ribbonWarning)
else resourceHelper.gc(R.color.ribbonDefault)
} ?: resourceHelper.gc(R.color.ribbonTextDefault)
val profileTextColor =
profileFunction.getProfile()?.let {
val profile = (it as ProfileSealed.EPS).value
if (profile.originalPercentage != 100 || profile.originalTimeshift != 0L || profile.originalDuration != 0L)
resourceHelper.gc(R.color.ribbonTextWarning)
else resourceHelper.gc(R.color.ribbonTextDefault)
} ?: resourceHelper.gc(R.color.ribbonTextDefault)
binding.loopPumpStatusLayout.activeProfile.text = profileFunction.getProfileNameWithRemainingTime()
binding.loopPumpStatusLayout.activeProfile.setBackgroundColor(profileBackgroundColor)
binding.loopPumpStatusLayout.activeProfile.setTextColor(profileTextColor)
} }
OverviewData.Property.TEMPORARY_BASAL -> { OverviewData.Property.TEMPORARY_BASAL -> {
@ -710,7 +726,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, resourceHelper) binding.loopPumpStatusLayout.tempTarget.text = Profile.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, resourceHelper)
} else { } else {
// If the target is not the same as set in the profile then oref has overridden it // If the target is not the same as set in the profile then oref has overridden it
overviewData.profile?.let { profile -> profileFunction.getProfile()?.let { profile ->
val targetUsed = loopPlugin.lastRun?.constraintsProcessed?.targetBG ?: 0.0 val targetUsed = loopPlugin.lastRun?.constraintsProcessed?.targetBG ?: 0.0
if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) { if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) {

View file

@ -227,6 +227,7 @@ class OverviewPlugin @Inject constructor(
if (runningRefresh) return if (runningRefresh) return
runningRefresh = true runningRefresh = true
loadIobCobResults(from) loadIobCobResults(from)
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.PROFILE))
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.BG)) overviewBus.send(EventUpdateOverview(from, OverviewData.Property.BG))
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TIME)) overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TIME))
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_BASAL)) overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_BASAL))
@ -264,9 +265,6 @@ class OverviewPlugin @Inject constructor(
} }
private fun loadProfile(from: String) { private fun loadProfile(from: String) {
overviewData.profile = profileFunction.getProfile()
overviewData.profileName = profileFunction.getProfileName()
overviewData.profileNameWithRemainingTime = profileFunction.getProfileNameWithRemainingTime()
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.PROFILE)) overviewBus.send(EventUpdateOverview(from, OverviewData.Property.PROFILE))
} }

View file

@ -9,6 +9,7 @@ import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration
@ -43,10 +44,17 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector
} }
override fun doAction(callback: Callback) { override fun doAction(callback: Callback) {
uel.log(UserEntry.Action.PROFILE_SWITCH, Sources.Automation, title + ": " + resourceHelper.gs(R.string.startprofile, pct.value.toInt(), duration.value), if (profileFunction.createProfileSwitch(duration.value, pct.value.toInt(), 0)) {
ValueWithUnit.Percent(pct.value.toInt()), uel.log(
ValueWithUnit.Minute(duration.value)) UserEntry.Action.PROFILE_SWITCH,
profileFunction.createProfileSwitch(duration.value, pct.value.toInt(), 0) Sources.Automation,
title + ": " + resourceHelper.gs(R.string.startprofile, pct.value.toInt(), duration.value),
ValueWithUnit.Percent(pct.value.toInt()),
ValueWithUnit.Minute(duration.value)
)
} else {
aapsLogger.error(LTag.AUTOMATION, "Final profile not valid")
}
callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run()
} }

View file

@ -145,7 +145,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
TriggerWifiSsid::class.java.simpleName -> TriggerWifiSsid(injector).fromJSON( TriggerWifiSsid::class.java.simpleName -> TriggerWifiSsid(injector).fromJSON(
data.toString() data.toString()
) )
else -> throw ClassNotFoundException(type) else -> TriggerConnector(injector)
} }
} }

View file

@ -76,8 +76,9 @@ interface ProfileFunction {
* @param durationInMinutes * @param durationInMinutes
* @param percentage 100 = no modification * @param percentage 100 = no modification
* @param timeShiftInHours 0 = no modification * @param timeShiftInHours 0 = no modification
* @return true if profile switch is created
*/ */
fun createProfileSwitch(durationInMinutes: Int, percentage: Int, timeShiftInHours: Int) fun createProfileSwitch(durationInMinutes: Int, percentage: Int, timeShiftInHours: Int): Boolean
/* /*
* Midnight time conversion * Midnight time conversion

View file

@ -16,7 +16,7 @@
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.warning.mode=all
org.gradle.jvmargs=-Xmx2g org.gradle.jvmargs=-Xmx2g
android.enableJetifier=true android.enableJetifier=true