Merge branch 'dev' of https://github.com/nightscout/AndroidAPS into dev
This commit is contained in:
commit
4bf3879377
69 changed files with 1816 additions and 1318 deletions
|
@ -109,7 +109,7 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "3.0.0.1-dev-h"
|
version "3.0.0.1-dev-i"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||||
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
||||||
|
|
|
@ -13,7 +13,6 @@ import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.data.ProfileSealed
|
import info.nightscout.androidaps.data.ProfileSealed
|
||||||
import info.nightscout.androidaps.database.interfaces.end
|
import info.nightscout.androidaps.database.interfaces.end
|
||||||
import info.nightscout.androidaps.extensions.directionToIcon
|
import info.nightscout.androidaps.extensions.directionToIcon
|
||||||
import info.nightscout.androidaps.extensions.isInProgress
|
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.extensions.valueToUnitsString
|
import info.nightscout.androidaps.extensions.valueToUnitsString
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
|
@ -78,7 +77,7 @@ class Widget : AppWidgetProvider() {
|
||||||
|
|
||||||
// Create an Intent to launch MainActivity when clicked
|
// Create an Intent to launch MainActivity when clicked
|
||||||
val intent = Intent(context, MainActivity::class.java).also { it.action = intentAction }
|
val intent = Intent(context, MainActivity::class.java).also { it.action = intentAction }
|
||||||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
|
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
// Widgets allow click handlers to only launch pending intents
|
// Widgets allow click handlers to only launch pending intents
|
||||||
views.setOnClickPendingIntent(R.id.widget_layout, pendingIntent)
|
views.setOnClickPendingIntent(R.id.widget_layout, pendingIntent)
|
||||||
|
|
||||||
|
@ -105,7 +104,11 @@ class Widget : AppWidgetProvider() {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
views.setImageViewResource(R.id.arrow, trendCalculator.getTrendArrow(overviewData.lastBg).directionToIcon())
|
views.setImageViewResource(R.id.arrow, trendCalculator.getTrendArrow(overviewData.lastBg).directionToIcon())
|
||||||
//binding.infoLayout.arrow.setColorFilter(overviewData.lastBgColor(context))
|
views.setInt(R.id.arrow, "setColorFilter", when {
|
||||||
|
overviewData.isLow -> rh.gc(R.color.low)
|
||||||
|
overviewData.isHigh -> rh.gc(R.color.high)
|
||||||
|
else -> rh.gc(R.color.inrange)
|
||||||
|
})
|
||||||
|
|
||||||
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
|
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
|
||||||
if (glucoseStatus != null) {
|
if (glucoseStatus != null) {
|
||||||
|
@ -127,21 +130,21 @@ class Widget : AppWidgetProvider() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTemporaryBasal(views: RemoteViews) {
|
private fun updateTemporaryBasal(views: RemoteViews) {
|
||||||
views.setTextViewText(R.id.base_basal, overviewData.temporaryBasalText)
|
views.setTextViewText(R.id.base_basal, overviewData.temporaryBasalText(iobCobCalculator))
|
||||||
views.setTextColor(R.id.base_basal, overviewData.temporaryBasalColor)
|
views.setTextColor(R.id.base_basal, overviewData.temporaryBasalColor(iobCobCalculator))
|
||||||
views.setImageViewResource(R.id.base_basal_icon, overviewData.temporaryBasalIcon)
|
views.setImageViewResource(R.id.base_basal_icon, overviewData.temporaryBasalIcon(iobCobCalculator))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateExtendedBolus(views: RemoteViews) {
|
private fun updateExtendedBolus(views: RemoteViews) {
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
views.setTextViewText(R.id.extended_bolus, overviewData.extendedBolusText)
|
views.setTextViewText(R.id.extended_bolus, overviewData.extendedBolusText(iobCobCalculator))
|
||||||
views.setViewVisibility(R.id.extended_layout, (iobCobCalculator.getExtendedBolus(dateUtil.now()) != null && !pump.isFakingTempsByExtendedBoluses).toVisibility())
|
views.setViewVisibility(R.id.extended_layout, (iobCobCalculator.getExtendedBolus(dateUtil.now()) != null && !pump.isFakingTempsByExtendedBoluses).toVisibility())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateIobCob(views: RemoteViews) {
|
private fun updateIobCob(views: RemoteViews) {
|
||||||
views.setTextViewText(R.id.iob, overviewData.iobText)
|
views.setTextViewText(R.id.iob, overviewData.iobText(iobCobCalculator))
|
||||||
// cob
|
// cob
|
||||||
var cobText = overviewData.cobInfo?.displayText(rh, dateUtil, isDev = false) ?: rh.gs(R.string.value_unavailable_short)
|
var cobText = overviewData.cobInfo(iobCobCalculator).displayText(rh, dateUtil, isDev = false) ?: rh.gs(R.string.value_unavailable_short)
|
||||||
|
|
||||||
val constraintsProcessed = loop.lastRun?.constraintsProcessed
|
val constraintsProcessed = loop.lastRun?.constraintsProcessed
|
||||||
val lastRun = loop.lastRun
|
val lastRun = loop.lastRun
|
||||||
|
@ -158,7 +161,6 @@ class Widget : AppWidgetProvider() {
|
||||||
|
|
||||||
private fun updateTemporaryTarget(views: RemoteViews) {
|
private fun updateTemporaryTarget(views: RemoteViews) {
|
||||||
val units = profileFunction.getUnits()
|
val units = profileFunction.getUnits()
|
||||||
if (overviewData.temporaryTarget?.isInProgress(dateUtil) == false) overviewData.temporaryTarget = null
|
|
||||||
val tempTarget = overviewData.temporaryTarget
|
val tempTarget = overviewData.temporaryTarget
|
||||||
if (tempTarget != null) {
|
if (tempTarget != null) {
|
||||||
// this is crashing, use background as text for now
|
// this is crashing, use background as text for now
|
||||||
|
@ -210,12 +212,12 @@ class Widget : AppWidgetProvider() {
|
||||||
views.setTextColor(R.id.active_profile, profileTextColor)
|
views.setTextColor(R.id.active_profile, profileTextColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSensitivity(views: RemoteViews) {
|
private fun updateSensitivity(views: RemoteViews) {
|
||||||
if (sp.getBoolean(R.string.key_openapsama_useautosens, false) && constraintChecker.isAutosensModeEnabled().value())
|
if (sp.getBoolean(R.string.key_openapsama_useautosens, false) && constraintChecker.isAutosensModeEnabled().value())
|
||||||
views.setImageViewResource(R.id.sensitivity_icon, R.drawable.ic_swap_vert_black_48dp_green)
|
views.setImageViewResource(R.id.sensitivity_icon, R.drawable.ic_swap_vert_black_48dp_green)
|
||||||
else
|
else
|
||||||
views.setImageViewResource(R.id.sensitivity_icon, R.drawable.ic_x_swap_vert)
|
views.setImageViewResource(R.id.sensitivity_icon, R.drawable.ic_x_swap_vert)
|
||||||
views.setTextViewText(R.id.sensitivity, overviewData.lastAutosensData?.let { autosensData ->
|
views.setTextViewText(R.id.sensitivity, overviewData.lastAutosensData(iobCobCalculator)?.let { autosensData ->
|
||||||
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
|
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
|
||||||
} ?: "")
|
} ?: "")
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.activities
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.DatePickerDialog
|
import android.app.DatePickerDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -19,21 +18,18 @@ import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||||
import info.nightscout.androidaps.events.EventCustomCalculationFinished
|
import info.nightscout.androidaps.events.EventCustomCalculationFinished
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview
|
import info.nightscout.androidaps.events.EventRefreshOverview
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
|
import info.nightscout.androidaps.extensions.toVisibilityKeepSpace
|
||||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
import info.nightscout.androidaps.interfaces.Config
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
import info.nightscout.androidaps.interfaces.Loop
|
import info.nightscout.androidaps.interfaces.Loop
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
||||||
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
|
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewGraph
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
|
||||||
import info.nightscout.androidaps.receivers.DataWorker
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
|
@ -42,6 +38,7 @@ import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.Translator
|
import info.nightscout.androidaps.utils.Translator
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.androidaps.workflow.CalculationWorkflow
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
@ -59,9 +56,6 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
@Inject lateinit var activePlugin: ActivePlugin
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
@Inject lateinit var buildHelper: BuildHelper
|
@Inject lateinit var buildHelper: BuildHelper
|
||||||
@Inject lateinit var sensitivityOref1Plugin: SensitivityOref1Plugin
|
|
||||||
@Inject lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin
|
|
||||||
@Inject lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin
|
|
||||||
@Inject lateinit var repository: AppRepository
|
@Inject lateinit var repository: AppRepository
|
||||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||||
@Inject lateinit var overviewMenus: OverviewMenus
|
@Inject lateinit var overviewMenus: OverviewMenus
|
||||||
|
@ -72,6 +66,7 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
@Inject lateinit var translator: Translator
|
@Inject lateinit var translator: Translator
|
||||||
@Inject lateinit var context: Context
|
@Inject lateinit var context: Context
|
||||||
@Inject lateinit var dataWorker: DataWorker
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var calculationWorkflow: CalculationWorkflow
|
||||||
|
|
||||||
private val disposable = CompositeDisposable()
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
@ -94,6 +89,17 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
// We don't want to use injected singletons but own instance working on top of different data
|
// We don't want to use injected singletons but own instance working on top of different data
|
||||||
|
overviewData =
|
||||||
|
OverviewData(
|
||||||
|
aapsLogger,
|
||||||
|
rh,
|
||||||
|
dateUtil,
|
||||||
|
sp,
|
||||||
|
activePlugin,
|
||||||
|
defaultValueHelper,
|
||||||
|
profileFunction,
|
||||||
|
repository
|
||||||
|
)
|
||||||
iobCobCalculator =
|
iobCobCalculator =
|
||||||
IobCobCalculatorPlugin(
|
IobCobCalculatorPlugin(
|
||||||
injector,
|
injector,
|
||||||
|
@ -104,32 +110,11 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
rh,
|
rh,
|
||||||
profileFunction,
|
profileFunction,
|
||||||
activePlugin,
|
activePlugin,
|
||||||
sensitivityOref1Plugin,
|
|
||||||
sensitivityAAPSPlugin,
|
|
||||||
sensitivityWeightedAveragePlugin,
|
|
||||||
fabricPrivacy,
|
fabricPrivacy,
|
||||||
dateUtil,
|
dateUtil,
|
||||||
repository,
|
repository,
|
||||||
context,
|
overviewData,
|
||||||
dataWorker
|
calculationWorkflow
|
||||||
)
|
|
||||||
overviewData =
|
|
||||||
OverviewData(
|
|
||||||
injector,
|
|
||||||
aapsLogger,
|
|
||||||
rh,
|
|
||||||
dateUtil,
|
|
||||||
sp,
|
|
||||||
activePlugin,
|
|
||||||
defaultValueHelper,
|
|
||||||
profileFunction,
|
|
||||||
config,
|
|
||||||
loop,
|
|
||||||
nsDeviceStatus,
|
|
||||||
repository,
|
|
||||||
overviewMenus,
|
|
||||||
iobCobCalculator,
|
|
||||||
translator
|
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.left.setOnClickListener {
|
binding.left.setOnClickListener {
|
||||||
|
@ -201,7 +186,7 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
|
|
||||||
|
|
||||||
axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80
|
axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80
|
||||||
binding.bgGraph.gridLabelRenderer?.gridColor = rh.gac(this, R.attr.graphgrid)
|
binding.bgGraph.gridLabelRenderer?.gridColor = rh.gac(this, R.attr.graphgrid)
|
||||||
binding.bgGraph.gridLabelRenderer?.reloadStyles()
|
binding.bgGraph.gridLabelRenderer?.reloadStyles()
|
||||||
binding.bgGraph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
binding.bgGraph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||||
|
|
||||||
|
@ -217,7 +202,7 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
disposable.clear()
|
disposable.clear()
|
||||||
iobCobCalculator.stopCalculation("onPause")
|
calculationWorkflow.stopCalculation(CalculationWorkflow.HISTORY_CALCULATION, "onPause")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -239,22 +224,11 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventIobCalculationProgress::class.java)
|
.toObservable(EventIobCalculationProgress::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({
|
.subscribe({ updateCalcProgress(it.pass.finalPercent(it.progressPct)) }, fabricPrivacy::logException)
|
||||||
if (it.cause is EventCustomCalculationFinished)
|
|
||||||
binding.overviewIobcalculationprogess.text = it.progressPct.toString() + "%"
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventRefreshOverview::class.java)
|
.toObservable(EventUpdateOverviewGraph::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updateGUI("EventRefreshOverview") }, fabricPrivacy::logException)
|
.subscribe({ updateGUI("EventRefreshOverview") }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventBucketedDataCreated::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({
|
|
||||||
overviewData.prepareBucketedData("EventBucketedDataCreated")
|
|
||||||
overviewData.prepareBgData("EventBucketedDataCreated")
|
|
||||||
rxBus.send(EventRefreshOverview("EventBucketedDataCreated"))
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
|
|
||||||
if (overviewData.fromTime == 0L) {
|
if (overviewData.fromTime == 0L) {
|
||||||
// set start of current day
|
// set start of current day
|
||||||
|
@ -285,12 +259,12 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
|
|
||||||
val graph = GraphView(this)
|
val graph = GraphView(this)
|
||||||
graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, rh.dpToPx(100)).also { it.setMargins(0, rh.dpToPx(15), 0, rh.dpToPx(10)) }
|
graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, rh.dpToPx(100)).also { it.setMargins(0, rh.dpToPx(15), 0, rh.dpToPx(10)) }
|
||||||
graph.gridLabelRenderer?.gridColor = rh.gac( R.attr.graphgrid)
|
graph.gridLabelRenderer?.gridColor = rh.gac(R.attr.graphgrid)
|
||||||
graph.gridLabelRenderer?.reloadStyles()
|
graph.gridLabelRenderer?.reloadStyles()
|
||||||
graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
|
graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
|
||||||
graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||||
graph.gridLabelRenderer?.numVerticalLabels = 3
|
graph.gridLabelRenderer?.numVerticalLabels = 3
|
||||||
graph.viewport.backgroundColor =rh.gac(this , R.attr.viewPortbackgroundColor)
|
graph.viewport.backgroundColor = rh.gac(this, R.attr.viewPortbackgroundColor)
|
||||||
relativeLayout.addView(graph)
|
relativeLayout.addView(graph)
|
||||||
|
|
||||||
val label = TextView(this)
|
val label = TextView(this)
|
||||||
|
@ -310,17 +284,7 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
@Suppress("SameParameterValue")
|
@Suppress("SameParameterValue")
|
||||||
private fun loadAll(from: String) {
|
private fun loadAll(from: String) {
|
||||||
updateDate()
|
updateDate()
|
||||||
Thread {
|
runCalculation(from)
|
||||||
overviewData.prepareBgData(from)
|
|
||||||
overviewData.prepareTreatmentsData(from)
|
|
||||||
rxBus.send(EventRefreshOverview("loadAll_$from"))
|
|
||||||
overviewData.prepareTemporaryTargetData(from)
|
|
||||||
rxBus.send(EventRefreshOverview("loadAll_$from"))
|
|
||||||
overviewData.prepareBasalData(from)
|
|
||||||
rxBus.send(EventRefreshOverview(from))
|
|
||||||
aapsLogger.debug(LTag.UI, "loadAll $from finished")
|
|
||||||
runCalculation(from)
|
|
||||||
}.start()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setTime(start: Long) {
|
private fun setTime(start: Long) {
|
||||||
|
@ -341,22 +305,32 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runCalculation(from: String) {
|
private fun runCalculation(from: String) {
|
||||||
iobCobCalculator.runCalculation(from, overviewData.toTime, bgDataReload = true, limitDataToOldestAvailable = false, cause = EventCustomCalculationFinished())
|
calculationWorkflow.runCalculation(
|
||||||
|
CalculationWorkflow.HISTORY_CALCULATION,
|
||||||
|
iobCobCalculator,
|
||||||
|
overviewData,
|
||||||
|
from,
|
||||||
|
overviewData.toTime,
|
||||||
|
bgDataReload = true,
|
||||||
|
limitDataToOldestAvailable = false,
|
||||||
|
cause = EventCustomCalculationFinished(),
|
||||||
|
runLoop = false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
var runningRefresh = false
|
var runningRefresh = false
|
||||||
|
|
||||||
@Suppress("SameParameterValue")
|
@Suppress("SameParameterValue")
|
||||||
private fun refreshLoop(from: String) {
|
private fun refreshLoop(from: String) {
|
||||||
if (runningRefresh) return
|
if (runningRefresh) return
|
||||||
runningRefresh = true
|
runningRefresh = true
|
||||||
overviewData.prepareIobAutosensData(from)
|
|
||||||
rxBus.send(EventRefreshOverview(from))
|
rxBus.send(EventRefreshOverview(from))
|
||||||
aapsLogger.debug(LTag.UI, "refreshLoop finished")
|
aapsLogger.debug(LTag.UI, "refreshLoop finished")
|
||||||
runningRefresh = false
|
runningRefresh = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateDate() {
|
private fun updateDate() {
|
||||||
binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime)
|
binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime)
|
||||||
binding.zoom.text = rangeToDisplay.toString()
|
binding.zoom.text = rangeToDisplay.toString()
|
||||||
}
|
}
|
||||||
|
@ -403,12 +377,12 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
var useDSForScale = false
|
var useDSForScale = false
|
||||||
var useBGIForScale = false
|
var useBGIForScale = false
|
||||||
when {
|
when {
|
||||||
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
|
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
|
||||||
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
|
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
|
||||||
menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
|
menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
|
||||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
|
menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
|
||||||
menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] -> useBGIForScale = true
|
menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] -> useBGIForScale = true
|
||||||
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
|
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
|
||||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
|
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
|
||||||
}
|
}
|
||||||
val alignDevBgiScale = menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] && menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]
|
val alignDevBgiScale = menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] && menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]
|
||||||
|
@ -440,4 +414,9 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||||
secondaryGraphsData[g].performUpdate()
|
secondaryGraphsData[g].performUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateCalcProgress(percent: Int) {
|
||||||
|
binding.progressBar.progress = percent
|
||||||
|
binding.progressBar.visibility = (percent != 100).toVisibilityKeepSpace()
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -24,9 +24,7 @@ import info.nightscout.androidaps.database.transactions.InvalidateCarbsTransacti
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsBolusCarbsFragmentBinding
|
import info.nightscout.androidaps.databinding.TreatmentsBolusCarbsFragmentBinding
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsBolusCarbsItemBinding
|
import info.nightscout.androidaps.databinding.TreatmentsBolusCarbsItemBinding
|
||||||
import info.nightscout.androidaps.dialogs.WizardInfoDialog
|
import info.nightscout.androidaps.dialogs.WizardInfoDialog
|
||||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
|
||||||
import info.nightscout.androidaps.events.EventTreatmentChange
|
import info.nightscout.androidaps.events.EventTreatmentChange
|
||||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
|
||||||
import info.nightscout.androidaps.extensions.iobCalc
|
import info.nightscout.androidaps.extensions.iobCalc
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
|
@ -170,16 +168,6 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -334,7 +322,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
||||||
showInvalidated = true
|
showInvalidated = true
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +330,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
||||||
showInvalidated = false
|
showInvalidated = false
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import info.nightscout.androidaps.database.transactions.InvalidateTherapyEventTr
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsCareportalFragmentBinding
|
import info.nightscout.androidaps.databinding.TreatmentsCareportalFragmentBinding
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsCareportalItemBinding
|
import info.nightscout.androidaps.databinding.TreatmentsCareportalItemBinding
|
||||||
import info.nightscout.androidaps.events.EventTherapyEventChange
|
import info.nightscout.androidaps.events.EventTherapyEventChange
|
||||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
@ -128,11 +127,6 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -216,7 +210,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
||||||
showInvalidated = true
|
showInvalidated = true
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +218,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
||||||
showInvalidated = false
|
showInvalidated = false
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import info.nightscout.androidaps.database.transactions.InvalidateExtendedBolusT
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsExtendedbolusFragmentBinding
|
import info.nightscout.androidaps.databinding.TreatmentsExtendedbolusFragmentBinding
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsExtendedbolusItemBinding
|
import info.nightscout.androidaps.databinding.TreatmentsExtendedbolusItemBinding
|
||||||
import info.nightscout.androidaps.events.EventExtendedBolusChange
|
import info.nightscout.androidaps.events.EventExtendedBolusChange
|
||||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
|
||||||
import info.nightscout.androidaps.extensions.iobCalc
|
import info.nightscout.androidaps.extensions.iobCalc
|
||||||
import info.nightscout.androidaps.extensions.isInProgress
|
import info.nightscout.androidaps.extensions.isInProgress
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
|
@ -105,11 +104,6 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -203,7 +197,7 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
||||||
showInvalidated = true
|
showInvalidated = true
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +205,7 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
||||||
showInvalidated = false
|
showInvalidated = false
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import info.nightscout.androidaps.databinding.TreatmentsProfileswitchItemBinding
|
||||||
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
||||||
import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged
|
import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged
|
||||||
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
||||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
|
||||||
import info.nightscout.androidaps.extensions.getCustomizedName
|
import info.nightscout.androidaps.extensions.getCustomizedName
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
|
@ -47,7 +46,6 @@ import io.reactivex.rxjava3.core.Completable
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
||||||
|
@ -162,11 +160,6 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
||||||
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
|
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -306,7 +299,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
||||||
showInvalidated = true
|
showInvalidated = true
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +307,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
||||||
showInvalidated = false
|
showInvalidated = false
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ import info.nightscout.androidaps.databinding.TreatmentsTemptargetItemBinding
|
||||||
import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged
|
import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged
|
||||||
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
||||||
import info.nightscout.androidaps.events.EventTempTargetChange
|
import info.nightscout.androidaps.events.EventTempTargetChange
|
||||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
|
||||||
import info.nightscout.androidaps.extensions.friendlyDescription
|
import info.nightscout.androidaps.extensions.friendlyDescription
|
||||||
import info.nightscout.androidaps.extensions.highValueToUnitsToString
|
import info.nightscout.androidaps.extensions.highValueToUnitsToString
|
||||||
import info.nightscout.androidaps.extensions.lowValueToUnitsToString
|
import info.nightscout.androidaps.extensions.lowValueToUnitsToString
|
||||||
|
@ -134,11 +133,6 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -235,7 +229,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
||||||
showInvalidated = true
|
showInvalidated = true
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +237,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
||||||
showInvalidated = false
|
showInvalidated = false
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,7 @@ import info.nightscout.androidaps.database.transactions.InvalidateExtendedBolusT
|
||||||
import info.nightscout.androidaps.database.transactions.InvalidateTemporaryBasalTransaction
|
import info.nightscout.androidaps.database.transactions.InvalidateTemporaryBasalTransaction
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsTempbasalsFragmentBinding
|
import info.nightscout.androidaps.databinding.TreatmentsTempbasalsFragmentBinding
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsTempbasalsItemBinding
|
import info.nightscout.androidaps.databinding.TreatmentsTempbasalsItemBinding
|
||||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
|
||||||
import info.nightscout.androidaps.events.EventTempBasalChange
|
import info.nightscout.androidaps.events.EventTempBasalChange
|
||||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
|
||||||
import info.nightscout.androidaps.extensions.iobCalc
|
import info.nightscout.androidaps.extensions.iobCalc
|
||||||
import info.nightscout.androidaps.extensions.toStringFull
|
import info.nightscout.androidaps.extensions.toStringFull
|
||||||
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
||||||
|
@ -141,15 +139,6 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
||||||
.toObservable(EventTempBasalChange::class.java)
|
.toObservable(EventTempBasalChange::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -183,7 +172,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
||||||
holder.binding.date.text = if (newDay) dateUtil.dateStringRelative(tempBasal.timestamp, rh) else ""
|
holder.binding.date.text = if (newDay) dateUtil.dateStringRelative(tempBasal.timestamp, rh) else ""
|
||||||
if (tempBasal.isInProgress) {
|
if (tempBasal.isInProgress) {
|
||||||
holder.binding.time.text = dateUtil.timeString(tempBasal.timestamp)
|
holder.binding.time.text = dateUtil.timeString(tempBasal.timestamp)
|
||||||
holder.binding.time.setTextColor(rh.gac(context , R.attr.activeColor))
|
holder.binding.time.setTextColor(rh.gac(context, R.attr.activeColor))
|
||||||
} else {
|
} else {
|
||||||
holder.binding.time.text = dateUtil.timeRangeString(tempBasal.timestamp, tempBasal.end)
|
holder.binding.time.text = dateUtil.timeRangeString(tempBasal.timestamp, tempBasal.end)
|
||||||
holder.binding.time.setTextColor(holder.binding.duration.currentTextColor)
|
holder.binding.time.setTextColor(holder.binding.duration.currentTextColor)
|
||||||
|
@ -200,7 +189,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
||||||
holder.binding.suspendFlag.visibility = (tempBasal.type == TemporaryBasal.Type.PUMP_SUSPEND).toVisibility()
|
holder.binding.suspendFlag.visibility = (tempBasal.type == TemporaryBasal.Type.PUMP_SUSPEND).toVisibility()
|
||||||
holder.binding.emulatedSuspendFlag.visibility = (tempBasal.type == TemporaryBasal.Type.EMULATED_PUMP_SUSPEND).toVisibility()
|
holder.binding.emulatedSuspendFlag.visibility = (tempBasal.type == TemporaryBasal.Type.EMULATED_PUMP_SUSPEND).toVisibility()
|
||||||
holder.binding.superBolusFlag.visibility = (tempBasal.type == TemporaryBasal.Type.SUPERBOLUS).toVisibility()
|
holder.binding.superBolusFlag.visibility = (tempBasal.type == TemporaryBasal.Type.SUPERBOLUS).toVisibility()
|
||||||
if (abs(iob.basaliob) > 0.01) holder.binding.iob.setTextColor(rh.gac(context , R.attr.activeColor)) else holder.binding.iob.setTextColor(holder.binding.duration.currentTextColor)
|
if (abs(iob.basaliob) > 0.01) holder.binding.iob.setTextColor(rh.gac(context, R.attr.activeColor)) else holder.binding.iob.setTextColor(holder.binding.duration.currentTextColor)
|
||||||
holder.binding.cbRemove.visibility = (tempBasal.isValid && actionHelper.isRemoving).toVisibility()
|
holder.binding.cbRemove.visibility = (tempBasal.isValid && actionHelper.isRemoving).toVisibility()
|
||||||
if (actionHelper.isRemoving) {
|
if (actionHelper.isRemoving) {
|
||||||
holder.binding.cbRemove.setOnCheckedChangeListener { _, value ->
|
holder.binding.cbRemove.setOnCheckedChangeListener { _, value ->
|
||||||
|
@ -251,7 +240,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
||||||
showInvalidated = true
|
showInvalidated = true
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +248,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
||||||
showInvalidated = false
|
showInvalidated = false
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.hide_invalidated_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,41 +270,41 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
||||||
private fun removeSelected(selectedItems: SparseArray<TemporaryBasal>) {
|
private fun removeSelected(selectedItems: SparseArray<TemporaryBasal>) {
|
||||||
if (selectedItems.size() > 0)
|
if (selectedItems.size() > 0)
|
||||||
activity?.let { activity ->
|
activity?.let { activity ->
|
||||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(selectedItems), Runnable {
|
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(selectedItems), Runnable {
|
||||||
selectedItems.forEach {_, tempBasal ->
|
selectedItems.forEach { _, tempBasal ->
|
||||||
var extendedBolus: ExtendedBolus? = null
|
var extendedBolus: ExtendedBolus? = null
|
||||||
val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED
|
val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED
|
||||||
if (isFakeExtended) {
|
if (isFakeExtended) {
|
||||||
val eb = repository.getExtendedBolusActiveAt(tempBasal.timestamp).blockingGet()
|
val eb = repository.getExtendedBolusActiveAt(tempBasal.timestamp).blockingGet()
|
||||||
extendedBolus = if (eb is ValueWrapper.Existing) eb.value else null
|
extendedBolus = if (eb is ValueWrapper.Existing) eb.value else null
|
||||||
|
}
|
||||||
|
if (isFakeExtended && extendedBolus != null) {
|
||||||
|
uel.log(
|
||||||
|
Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||||
|
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||||
|
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||||
|
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||||
|
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt())
|
||||||
|
)
|
||||||
|
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
||||||
|
.subscribe(
|
||||||
|
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
||||||
|
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
||||||
|
} else if (!isFakeExtended) {
|
||||||
|
uel.log(
|
||||||
|
Action.TEMP_BASAL_REMOVED, Sources.Treatments,
|
||||||
|
ValueWithUnit.Timestamp(tempBasal.timestamp),
|
||||||
|
if (tempBasal.isAbsolute) ValueWithUnit.UnitPerHour(tempBasal.rate) else ValueWithUnit.Percent(tempBasal.rate.toInt()),
|
||||||
|
ValueWithUnit.Minute(T.msecs(tempBasal.duration).mins().toInt())
|
||||||
|
)
|
||||||
|
disposable += repository.runTransactionForResult(InvalidateTemporaryBasalTransaction(tempBasal.id))
|
||||||
|
.subscribe(
|
||||||
|
{ aapsLogger.debug(LTag.DATABASE, "Removed temporary basal $tempBasal") },
|
||||||
|
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isFakeExtended && extendedBolus != null) {
|
actionHelper.finish()
|
||||||
uel.log(
|
})
|
||||||
Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
}
|
||||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
|
||||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
|
||||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
|
||||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt())
|
|
||||||
)
|
|
||||||
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
|
||||||
.subscribe(
|
|
||||||
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
|
||||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
|
||||||
} else if (!isFakeExtended) {
|
|
||||||
uel.log(
|
|
||||||
Action.TEMP_BASAL_REMOVED, Sources.Treatments,
|
|
||||||
ValueWithUnit.Timestamp(tempBasal.timestamp),
|
|
||||||
if (tempBasal.isAbsolute) ValueWithUnit.UnitPerHour(tempBasal.rate) else ValueWithUnit.Percent(tempBasal.rate.toInt()),
|
|
||||||
ValueWithUnit.Minute(T.msecs(tempBasal.duration).mins().toInt())
|
|
||||||
)
|
|
||||||
disposable += repository.runTransactionForResult(InvalidateTemporaryBasalTransaction(tempBasal.id))
|
|
||||||
.subscribe(
|
|
||||||
{ aapsLogger.debug(LTag.DATABASE, "Removed temporary basal $tempBasal") },
|
|
||||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
actionHelper.finish()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsUserEntryFragmentBinding
|
import info.nightscout.androidaps.databinding.TreatmentsUserEntryFragmentBinding
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsUserEntryItemBinding
|
import info.nightscout.androidaps.databinding.TreatmentsUserEntryItemBinding
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.interfaces.ImportExportPrefs
|
import info.nightscout.androidaps.interfaces.ImportExportPrefs
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
@ -30,7 +29,6 @@ import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
|
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TreatmentsUserEntryFragment : DaggerFragment() {
|
class TreatmentsUserEntryFragment : DaggerFragment() {
|
||||||
|
@ -99,11 +97,6 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
||||||
.toObservable(EventPreferenceChange::class.java)
|
.toObservable(EventPreferenceChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentUpdateGui::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -172,7 +165,7 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
||||||
showLoop = true
|
showLoop = true
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_loop_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_loop_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +173,7 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
||||||
showLoop = false
|
showLoop = false
|
||||||
updateMenuVisibility()
|
updateMenuVisibility()
|
||||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_hide_records))
|
ToastUtils.showToastInUiThread(context, rh.gs(R.string.show_hide_records))
|
||||||
rxBus.send(EventTreatmentUpdateGui())
|
swapAdapter()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,11 @@ class CompatDBHelper @Inject constructor(
|
||||||
rxBus.send(EventExtendedBolusChange())
|
rxBus.send(EventExtendedBolusChange())
|
||||||
rxBus.send(EventNewHistoryData(timestamp, false))
|
rxBus.send(EventNewHistoryData(timestamp, false))
|
||||||
}
|
}
|
||||||
|
it.filterIsInstance<EffectiveProfileSwitch>().firstOrNull()?.let { eps ->
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Firing EventEffectiveProfileSwitchChanged $eps")
|
||||||
|
rxBus.send(EventEffectiveProfileSwitchChanged(eps))
|
||||||
|
rxBus.send(EventNewHistoryData(eps.timestamp, false))
|
||||||
|
}
|
||||||
it.filterIsInstance<TemporaryTarget>().firstOrNull()?.let { tt ->
|
it.filterIsInstance<TemporaryTarget>().firstOrNull()?.let { tt ->
|
||||||
aapsLogger.debug(LTag.DATABASE, "Firing EventTempTargetChange $tt")
|
aapsLogger.debug(LTag.DATABASE, "Firing EventTempTargetChange $tt")
|
||||||
rxBus.send(EventTempTargetChange())
|
rxBus.send(EventTempTargetChange())
|
||||||
|
@ -76,10 +81,6 @@ class CompatDBHelper @Inject constructor(
|
||||||
aapsLogger.debug(LTag.DATABASE, "Firing EventProfileSwitchChanged $ps")
|
aapsLogger.debug(LTag.DATABASE, "Firing EventProfileSwitchChanged $ps")
|
||||||
rxBus.send(EventProfileSwitchChanged())
|
rxBus.send(EventProfileSwitchChanged())
|
||||||
}
|
}
|
||||||
it.filterIsInstance<EffectiveProfileSwitch>().firstOrNull()?.let { eps ->
|
|
||||||
aapsLogger.debug(LTag.DATABASE, "Firing EventEffectiveProfileSwitchChanged $eps")
|
|
||||||
rxBus.send(EventEffectiveProfileSwitchChanged(eps))
|
|
||||||
}
|
|
||||||
it.filterIsInstance<OfflineEvent>().firstOrNull()?.let { oe ->
|
it.filterIsInstance<OfflineEvent>().firstOrNull()?.let { oe ->
|
||||||
aapsLogger.debug(LTag.DATABASE, "Firing EventOfflineChange $oe")
|
aapsLogger.debug(LTag.DATABASE, "Firing EventOfflineChange $oe")
|
||||||
rxBus.send(EventOfflineChange())
|
rxBus.send(EventOfflineChange())
|
||||||
|
|
|
@ -8,8 +8,6 @@ import info.nightscout.androidaps.plugins.aps.openAPSAMA.DetermineBasalResultAMA
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalAdapterSMBJS
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalAdapterSMBJS
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMBDynamicISF.DetermineBasalAdapterSMBDynamicISFJS
|
import info.nightscout.androidaps.plugins.aps.openAPSSMBDynamicISF.DetermineBasalAdapterSMBDynamicISFJS
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Worker
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOrefWorker
|
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@ -21,6 +19,4 @@ abstract class APSModule {
|
||||||
@ContributesAndroidInjector abstract fun determineBasalAdapterAMAJSInjector(): DetermineBasalAdapterAMAJS
|
@ContributesAndroidInjector abstract fun determineBasalAdapterAMAJSInjector(): DetermineBasalAdapterAMAJS
|
||||||
@ContributesAndroidInjector abstract fun determineBasalAdapterSMBJSInjector(): DetermineBasalAdapterSMBJS
|
@ContributesAndroidInjector abstract fun determineBasalAdapterSMBJSInjector(): DetermineBasalAdapterSMBJS
|
||||||
@ContributesAndroidInjector abstract fun determineBasalAdapterSMBAutoISFJSInjector(): DetermineBasalAdapterSMBDynamicISFJS
|
@ContributesAndroidInjector abstract fun determineBasalAdapterSMBAutoISFJSInjector(): DetermineBasalAdapterSMBDynamicISFJS
|
||||||
@ContributesAndroidInjector abstract fun iobCobWorkerInjector(): IobCobOrefWorker
|
|
||||||
@ContributesAndroidInjector abstract fun iobCobOref1WorkerInjector(): IobCobOref1Worker
|
|
||||||
}
|
}
|
|
@ -46,6 +46,7 @@ import javax.inject.Singleton
|
||||||
OmnipodDashModule::class,
|
OmnipodDashModule::class,
|
||||||
OmnipodErosModule::class,
|
OmnipodErosModule::class,
|
||||||
APSModule::class,
|
APSModule::class,
|
||||||
|
WorkflowModule::class,
|
||||||
PreferencesModule::class,
|
PreferencesModule::class,
|
||||||
OverviewModule::class,
|
OverviewModule::class,
|
||||||
DataClassesModule::class,
|
DataClassesModule::class,
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package info.nightscout.androidaps.di
|
||||||
|
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.android.ContributesAndroidInjector
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.*
|
||||||
|
import info.nightscout.androidaps.workflow.*
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@Suppress("unused")
|
||||||
|
abstract class WorkflowModule {
|
||||||
|
|
||||||
|
@ContributesAndroidInjector abstract fun iobCobWorkerInjector(): IobCobOrefWorker
|
||||||
|
@ContributesAndroidInjector abstract fun iobCobOref1WorkerInjector(): IobCobOref1Worker
|
||||||
|
@ContributesAndroidInjector abstract fun prepareIobAutosensDataWorkerInjector(): PrepareIobAutosensGraphDataWorker
|
||||||
|
@ContributesAndroidInjector abstract fun prepareBasalDataWorkerInjector(): PrepareBasalDataWorker
|
||||||
|
@ContributesAndroidInjector abstract fun prepareTemporaryTargetDataWorkerInjector(): PrepareTemporaryTargetDataWorker
|
||||||
|
@ContributesAndroidInjector abstract fun prepareTreatmentsDataWorkerInjector(): PrepareTreatmentsDataWorker
|
||||||
|
@ContributesAndroidInjector abstract fun loadIobCobResultsWorkerInjector(): UpdateIobCobSensWorker
|
||||||
|
@ContributesAndroidInjector abstract fun preparePredictionsWorkerInjector(): PreparePredictionsWorker
|
||||||
|
@ContributesAndroidInjector abstract fun updateGraphAndIobWorkerInjector(): UpdateGraphWorker
|
||||||
|
@ContributesAndroidInjector abstract fun prepareBgDataWorkerInjector(): PrepareBgDataWorker
|
||||||
|
@ContributesAndroidInjector abstract fun prepareBucketedDataWorkerInjector(): PrepareBucketedDataWorker
|
||||||
|
@ContributesAndroidInjector abstract fun loadBgDataWorkerInjector(): LoadBgDataWorker
|
||||||
|
@ContributesAndroidInjector abstract fun invokeLoopWorkerInjector(): InvokeLoopWorker
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
package info.nightscout.androidaps.events
|
|
||||||
|
|
||||||
class EventReloadProfileSwitchData : Event()
|
|
|
@ -1,3 +0,0 @@
|
||||||
package info.nightscout.androidaps.events
|
|
||||||
|
|
||||||
class EventTreatmentUpdateGui : EventUpdateGui()
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.aps.events
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventLoopInvoked : Event()
|
|
|
@ -10,11 +10,13 @@ import android.content.Intent
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.*
|
import info.nightscout.androidaps.BuildConfig
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainActivity
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult
|
import info.nightscout.androidaps.data.PumpEnactResult
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.database.ValueWrapper
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
|
@ -25,13 +27,13 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||||
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentOfflineEventTransaction
|
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentOfflineEventTransaction
|
||||||
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
|
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
|
||||||
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange
|
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange
|
||||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
|
||||||
import info.nightscout.androidaps.events.EventNewBG
|
|
||||||
import info.nightscout.androidaps.events.EventTempTargetChange
|
import info.nightscout.androidaps.events.EventTempTargetChange
|
||||||
|
import info.nightscout.androidaps.extensions.buildDeviceStatus
|
||||||
|
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||||
|
import info.nightscout.androidaps.extensions.convertedToPercent
|
||||||
|
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.androidaps.interfaces.Loop.LastRun
|
import info.nightscout.androidaps.interfaces.Loop.LastRun
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.shared.logging.LTag
|
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui
|
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui
|
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui
|
||||||
|
@ -51,13 +53,10 @@ import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.HardLimits
|
import info.nightscout.androidaps.utils.HardLimits
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.extensions.buildDeviceStatus
|
|
||||||
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
|
||||||
import info.nightscout.androidaps.extensions.convertedToPercent
|
|
||||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventLoopInvoked
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
@ -88,20 +87,21 @@ class LoopPlugin @Inject constructor(
|
||||||
private val uel: UserEntryLogger,
|
private val uel: UserEntryLogger,
|
||||||
private val repository: AppRepository,
|
private val repository: AppRepository,
|
||||||
private val runningConfiguration: RunningConfiguration
|
private val runningConfiguration: RunningConfiguration
|
||||||
) : PluginBase(PluginDescription()
|
) : PluginBase(
|
||||||
.mainType(PluginType.LOOP)
|
PluginDescription()
|
||||||
.fragmentClass(LoopFragment::class.java.name)
|
.mainType(PluginType.LOOP)
|
||||||
.pluginIcon(R.drawable.ic_loop_closed_white)
|
.fragmentClass(LoopFragment::class.java.name)
|
||||||
.pluginName(R.string.loop)
|
.pluginIcon(R.drawable.ic_loop_closed_white)
|
||||||
.shortName(R.string.loop_shortname)
|
.pluginName(R.string.loop)
|
||||||
.preferencesId(R.xml.pref_loop)
|
.shortName(R.string.loop_shortname)
|
||||||
.enableByDefault(config.APS)
|
.preferencesId(R.xml.pref_loop)
|
||||||
.description(R.string.description_loop),
|
.enableByDefault(config.APS)
|
||||||
|
.description(R.string.description_loop),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Loop {
|
), Loop {
|
||||||
|
|
||||||
private val disposable = CompositeDisposable()
|
private val disposable = CompositeDisposable()
|
||||||
private var lastBgTriggeredRun: Long = 0
|
override var lastBgTriggeredRun: Long = 0
|
||||||
private var carbsSuggestionsSuspendedUntil: Long = 0
|
private var carbsSuggestionsSuspendedUntil: Long = 0
|
||||||
private var prevCarbsreq = 0
|
private var prevCarbsreq = 0
|
||||||
override var lastRun: LastRun? = null
|
override var lastRun: LastRun? = null
|
||||||
|
@ -109,39 +109,19 @@ class LoopPlugin @Inject constructor(
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
createNotificationChannel()
|
createNotificationChannel()
|
||||||
super.onStart()
|
super.onStart()
|
||||||
disposable.add(rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventTempTargetChange::class.java)
|
.toObservable(EventTempTargetChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ invoke("EventTempTargetChange", true) }, fabricPrivacy::logException)
|
.subscribe({ invoke("EventTempTargetChange", true) }, fabricPrivacy::logException)
|
||||||
)
|
|
||||||
/*
|
|
||||||
This method is triggered once autosens calculation has completed, so the LoopPlugin
|
|
||||||
has current data to work with. However, autosens calculation can be triggered by multiple
|
|
||||||
sources and currently only a new BG should trigger a loop run. Hence we return early if
|
|
||||||
the event causing the calculation is not EventNewBg.
|
|
||||||
<p>
|
|
||||||
*/
|
|
||||||
disposable.add(rxBus
|
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ event: EventAutosensCalculationFinished ->
|
|
||||||
// Autosens calculation not triggered by a new BG
|
|
||||||
if (event.cause !is EventNewBG) return@subscribe
|
|
||||||
val glucoseValue = iobCobCalculator.ads.actualBg() ?: return@subscribe
|
|
||||||
// BG outdated
|
|
||||||
// already looped with that value
|
|
||||||
if (glucoseValue.timestamp <= lastBgTriggeredRun) return@subscribe
|
|
||||||
lastBgTriggeredRun = glucoseValue.timestamp
|
|
||||||
invoke("AutosenseCalculation for $glucoseValue", true)
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNotificationChannel() {
|
private fun createNotificationChannel() {
|
||||||
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
@SuppressLint("WrongConstant") val channel = NotificationChannel(CHANNEL_ID,
|
@SuppressLint("WrongConstant") val channel = NotificationChannel(
|
||||||
CHANNEL_ID,
|
CHANNEL_ID,
|
||||||
NotificationManager.IMPORTANCE_HIGH)
|
CHANNEL_ID,
|
||||||
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
|
)
|
||||||
mNotificationManager.createNotificationChannel(channel)
|
mNotificationManager.createNotificationChannel(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +235,7 @@ class LoopPlugin @Inject constructor(
|
||||||
if (apsResult == null) {
|
if (apsResult == null) {
|
||||||
rxBus.send(EventLoopSetLastRunGui(rh.gs(R.string.noapsselected)))
|
rxBus.send(EventLoopSetLastRunGui(rh.gs(R.string.noapsselected)))
|
||||||
return
|
return
|
||||||
} else rxBus.send(EventLoopInvoked())
|
}
|
||||||
|
|
||||||
if (!isEmptyQueue()) {
|
if (!isEmptyQueue()) {
|
||||||
aapsLogger.debug(LTag.APS, rh.gs(R.string.pumpbusy))
|
aapsLogger.debug(LTag.APS, rh.gs(R.string.pumpbusy))
|
||||||
|
@ -296,9 +276,11 @@ class LoopPlugin @Inject constructor(
|
||||||
lastRun.lastTBRRequest = 0
|
lastRun.lastTBRRequest = 0
|
||||||
lastRun.lastSMBEnact = 0
|
lastRun.lastSMBEnact = 0
|
||||||
lastRun.lastSMBRequest = 0
|
lastRun.lastSMBRequest = 0
|
||||||
buildDeviceStatus(dateUtil, this, iobCobCalculator, profileFunction,
|
buildDeviceStatus(
|
||||||
|
dateUtil, this, iobCobCalculator, profileFunction,
|
||||||
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
||||||
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)?.also {
|
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION
|
||||||
|
)?.also {
|
||||||
repository.insert(it)
|
repository.insert(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +298,11 @@ class LoopPlugin @Inject constructor(
|
||||||
if (closedLoopEnabled.value()) {
|
if (closedLoopEnabled.value()) {
|
||||||
if (allowNotification) {
|
if (allowNotification) {
|
||||||
if (resultAfterConstraints.isCarbsRequired
|
if (resultAfterConstraints.isCarbsRequired
|
||||||
&& resultAfterConstraints.carbsReq >= sp.getInt(R.string.key_smb_enable_carbs_suggestions_threshold, 0) && carbsSuggestionsSuspendedUntil < System.currentTimeMillis() && !treatmentTimeThreshold(-15)) {
|
&& resultAfterConstraints.carbsReq >= sp.getInt(
|
||||||
|
R.string.key_smb_enable_carbs_suggestions_threshold,
|
||||||
|
0
|
||||||
|
) && carbsSuggestionsSuspendedUntil < System.currentTimeMillis() && !treatmentTimeThreshold(-15)
|
||||||
|
) {
|
||||||
if (sp.getBoolean(R.string.key_enable_carbs_required_alert_local, true) && !sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true)) {
|
if (sp.getBoolean(R.string.key_enable_carbs_required_alert_local, true) && !sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true)) {
|
||||||
val carbReqLocal = Notification(Notification.CARBS_REQUIRED, resultAfterConstraints.carbsRequiredText, Notification.NORMAL)
|
val carbReqLocal = Notification(Notification.CARBS_REQUIRED, resultAfterConstraints.carbsRequiredText, Notification.NORMAL)
|
||||||
rxBus.send(EventNewNotification(carbReqLocal))
|
rxBus.send(EventNewNotification(carbReqLocal))
|
||||||
|
@ -353,9 +339,11 @@ class LoopPlugin @Inject constructor(
|
||||||
|
|
||||||
// mId allows you to update the notification later on.
|
// mId allows you to update the notification later on.
|
||||||
mNotificationManager.notify(Constants.notificationID, builder.build())
|
mNotificationManager.notify(Constants.notificationID, builder.build())
|
||||||
uel.log(Action.CAREPORTAL, Sources.Loop, rh.gs(R.string.carbsreq, resultAfterConstraints.carbsReq, resultAfterConstraints.carbsReqWithin),
|
uel.log(
|
||||||
ValueWithUnit.Gram(resultAfterConstraints.carbsReq),
|
Action.CAREPORTAL, Sources.Loop, rh.gs(R.string.carbsreq, resultAfterConstraints.carbsReq, resultAfterConstraints.carbsReqWithin),
|
||||||
ValueWithUnit.Minute(resultAfterConstraints.carbsReqWithin))
|
ValueWithUnit.Gram(resultAfterConstraints.carbsReq),
|
||||||
|
ValueWithUnit.Minute(resultAfterConstraints.carbsReqWithin)
|
||||||
|
)
|
||||||
rxBus.send(EventNewOpenLoopNotification())
|
rxBus.send(EventNewOpenLoopNotification())
|
||||||
|
|
||||||
//only send to wear if Native notifications are turned off
|
//only send to wear if Native notifications are turned off
|
||||||
|
@ -373,7 +361,8 @@ class LoopPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (resultAfterConstraints.isChangeRequested
|
if (resultAfterConstraints.isChangeRequested
|
||||||
&& !commandQueue.bolusInQueue()) {
|
&& !commandQueue.bolusInQueue()
|
||||||
|
) {
|
||||||
val waiting = PumpEnactResult(injector)
|
val waiting = PumpEnactResult(injector)
|
||||||
waiting.queued = true
|
waiting.queued = true
|
||||||
if (resultAfterConstraints.tempBasalRequested) lastRun.tbrSetByPump = waiting
|
if (resultAfterConstraints.tempBasalRequested) lastRun.tbrSetByPump = waiting
|
||||||
|
@ -486,9 +475,11 @@ class LoopPlugin @Inject constructor(
|
||||||
lastRun.lastTBRRequest = lastRun.lastAPSRun
|
lastRun.lastTBRRequest = lastRun.lastAPSRun
|
||||||
lastRun.lastTBREnact = dateUtil.now()
|
lastRun.lastTBREnact = dateUtil.now()
|
||||||
lastRun.lastOpenModeAccept = dateUtil.now()
|
lastRun.lastOpenModeAccept = dateUtil.now()
|
||||||
buildDeviceStatus(dateUtil, this@LoopPlugin, iobCobCalculator, profileFunction,
|
buildDeviceStatus(
|
||||||
|
dateUtil, this@LoopPlugin, iobCobCalculator, profileFunction,
|
||||||
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
||||||
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)?.also {
|
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION
|
||||||
|
)?.also {
|
||||||
repository.insert(it)
|
repository.insert(it)
|
||||||
}
|
}
|
||||||
sp.incInt(R.string.key_ObjectivesmanualEnacts)
|
sp.incInt(R.string.key_ObjectivesmanualEnacts)
|
||||||
|
@ -531,8 +522,10 @@ class LoopPlugin @Inject constructor(
|
||||||
commandQueue.cancelTempBasal(false, callback)
|
commandQueue.cancelTempBasal(false, callback)
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
|
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
|
||||||
callback?.result(PumpEnactResult(injector).absolute(request.rate).duration(0)
|
callback?.result(
|
||||||
.enacted(false).success(true).comment(R.string.basal_set_correctly))?.run()
|
PumpEnactResult(injector).absolute(request.rate).duration(0)
|
||||||
|
.enacted(false).success(true).comment(R.string.basal_set_correctly)
|
||||||
|
)?.run()
|
||||||
}
|
}
|
||||||
} else if (request.usePercent && allowPercentage()) {
|
} else if (request.usePercent && allowPercentage()) {
|
||||||
if (request.percent == 100 && request.duration == 0) {
|
if (request.percent == 100 && request.duration == 0) {
|
||||||
|
@ -542,32 +535,52 @@ class LoopPlugin @Inject constructor(
|
||||||
commandQueue.cancelTempBasal(false, callback)
|
commandQueue.cancelTempBasal(false, callback)
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
|
aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly")
|
||||||
callback?.result(PumpEnactResult(injector).percent(request.percent).duration(0)
|
callback?.result(
|
||||||
.enacted(false).success(true).comment(R.string.basal_set_correctly))?.run()
|
PumpEnactResult(injector).percent(request.percent).duration(0)
|
||||||
|
.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.convertedToPercent(now, profile)) {
|
} else if (activeTemp != null && activeTemp.plannedRemainingMinutes > 5 && request.duration - activeTemp.plannedRemainingMinutes < 30 && request.percent == activeTemp.convertedToPercent(
|
||||||
|
now,
|
||||||
|
profile
|
||||||
|
)
|
||||||
|
) {
|
||||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
|
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
|
||||||
callback?.result(PumpEnactResult(injector).percent(request.percent)
|
callback?.result(
|
||||||
.enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes)
|
PumpEnactResult(injector).percent(request.percent)
|
||||||
.comment(R.string.let_temp_basal_run))?.run()
|
.enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes)
|
||||||
|
.comment(R.string.let_temp_basal_run)
|
||||||
|
)?.run()
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: tempBasalPercent()")
|
aapsLogger.debug(LTag.APS, "applyAPSRequest: tempBasalPercent()")
|
||||||
uel.log(Action.TEMP_BASAL, Sources.Loop,
|
uel.log(
|
||||||
|
Action.TEMP_BASAL, Sources.Loop,
|
||||||
ValueWithUnit.Percent(request.percent),
|
ValueWithUnit.Percent(request.percent),
|
||||||
ValueWithUnit.Minute(request.duration))
|
ValueWithUnit.Minute(request.duration)
|
||||||
|
)
|
||||||
commandQueue.tempBasalPercent(request.percent, request.duration, false, profile, PumpSync.TemporaryBasalType.NORMAL, callback)
|
commandQueue.tempBasalPercent(request.percent, request.duration, false, profile, PumpSync.TemporaryBasalType.NORMAL, callback)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (activeTemp != null && activeTemp.plannedRemainingMinutes > 5 && request.duration - activeTemp.plannedRemainingMinutes < 30 && abs(request.rate - activeTemp.convertedToAbsolute(now, profile)) < pump.pumpDescription.basalStep) {
|
if (activeTemp != null && activeTemp.plannedRemainingMinutes > 5 && request.duration - activeTemp.plannedRemainingMinutes < 30 && abs(
|
||||||
|
request.rate - activeTemp.convertedToAbsolute(
|
||||||
|
now,
|
||||||
|
profile
|
||||||
|
)
|
||||||
|
) < pump.pumpDescription.basalStep
|
||||||
|
) {
|
||||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
|
aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly")
|
||||||
callback?.result(PumpEnactResult(injector).absolute(activeTemp.convertedToAbsolute(now, profile))
|
callback?.result(
|
||||||
.enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes)
|
PumpEnactResult(injector).absolute(activeTemp.convertedToAbsolute(now, profile))
|
||||||
.comment(R.string.let_temp_basal_run))?.run()
|
.enacted(false).success(true).duration(activeTemp.plannedRemainingMinutes)
|
||||||
|
.comment(R.string.let_temp_basal_run)
|
||||||
|
)?.run()
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()")
|
aapsLogger.debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()")
|
||||||
uel.log(Action.TEMP_BASAL, Sources.Loop,
|
uel.log(
|
||||||
|
Action.TEMP_BASAL, Sources.Loop,
|
||||||
ValueWithUnit.UnitPerHour(request.rate),
|
ValueWithUnit.UnitPerHour(request.rate),
|
||||||
ValueWithUnit.Minute(request.duration))
|
ValueWithUnit.Minute(request.duration)
|
||||||
|
)
|
||||||
commandQueue.tempBasalAbsolute(request.rate, request.duration, false, profile, PumpSync.TemporaryBasalType.NORMAL, callback)
|
commandQueue.tempBasalAbsolute(request.rate, request.duration, false, profile, PumpSync.TemporaryBasalType.NORMAL, callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,9 +594,11 @@ class LoopPlugin @Inject constructor(
|
||||||
val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
|
val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
|
||||||
if (lastBolusTime != 0L && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
|
if (lastBolusTime != 0L && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
|
||||||
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
|
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
|
||||||
callback?.result(PumpEnactResult(injector)
|
callback?.result(
|
||||||
.comment(R.string.smb_frequency_exceeded)
|
PumpEnactResult(injector)
|
||||||
.enacted(false).success(false))?.run()
|
.comment(R.string.smb_frequency_exceeded)
|
||||||
|
.enacted(false).success(false)
|
||||||
|
)?.run()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!pump.isInitialized()) {
|
if (!pump.isInitialized()) {
|
||||||
|
@ -619,11 +634,11 @@ class LoopPlugin @Inject constructor(
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
disposable += repository.runTransactionForResult(InsertAndCancelCurrentOfflineEventTransaction(dateUtil.now(), T.mins(durationInMinutes.toLong()).msecs(), reason))
|
disposable += repository.runTransactionForResult(InsertAndCancelCurrentOfflineEventTransaction(dateUtil.now(), T.mins(durationInMinutes.toLong()).msecs(), reason))
|
||||||
.subscribe({ result ->
|
.subscribe({ result ->
|
||||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $it") }
|
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $it") }
|
||||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted OfflineEvent $it") }
|
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted OfflineEvent $it") }
|
||||||
}, {
|
}, {
|
||||||
aapsLogger.error(LTag.DATABASE, "Error while saving OfflineEvent", it)
|
aapsLogger.error(LTag.DATABASE, "Error while saving OfflineEvent", it)
|
||||||
})
|
})
|
||||||
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
||||||
commandQueue.tempBasalAbsolute(0.0, durationInMinutes, true, profile, PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND, object : Callback() {
|
commandQueue.tempBasalAbsolute(0.0, durationInMinutes, true, profile, PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND, object : Callback() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
|
@ -655,11 +670,11 @@ class LoopPlugin @Inject constructor(
|
||||||
override fun suspendLoop(durationInMinutes: Int) {
|
override fun suspendLoop(durationInMinutes: Int) {
|
||||||
disposable += repository.runTransactionForResult(InsertAndCancelCurrentOfflineEventTransaction(dateUtil.now(), T.mins(durationInMinutes.toLong()).msecs(), OfflineEvent.Reason.SUSPEND))
|
disposable += repository.runTransactionForResult(InsertAndCancelCurrentOfflineEventTransaction(dateUtil.now(), T.mins(durationInMinutes.toLong()).msecs(), OfflineEvent.Reason.SUSPEND))
|
||||||
.subscribe({ result ->
|
.subscribe({ result ->
|
||||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $it") }
|
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $it") }
|
||||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted OfflineEvent $it") }
|
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted OfflineEvent $it") }
|
||||||
}, {
|
}, {
|
||||||
aapsLogger.error(LTag.DATABASE, "Error while saving OfflineEvent", it)
|
aapsLogger.error(LTag.DATABASE, "Error while saving OfflineEvent", it)
|
||||||
})
|
})
|
||||||
commandQueue.cancelTempBasal(true, object : Callback() {
|
commandQueue.cancelTempBasal(true, object : Callback() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
|
|
|
@ -169,6 +169,9 @@ class PluginStore @Inject constructor(
|
||||||
override val activeSafety: Safety
|
override val activeSafety: Safety
|
||||||
get() = getSpecificPluginsListByInterface(Safety::class.java).first() as Safety
|
get() = getSpecificPluginsListByInterface(Safety::class.java).first() as Safety
|
||||||
|
|
||||||
|
override val activeIobCobCalculator: IobCobCalculator
|
||||||
|
get() = getSpecificPluginsListByInterface(IobCobCalculator::class.java).first() as IobCobCalculator
|
||||||
|
|
||||||
override fun getPluginsList(): ArrayList<PluginBase> = ArrayList(plugins)
|
override fun getPluginsList(): ArrayList<PluginBase> = ArrayList(plugins)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,11 @@ import android.content.pm.ResolveInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.events.*
|
import info.nightscout.androidaps.events.Event
|
||||||
|
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||||
import info.nightscout.androidaps.extensions.durationInMinutes
|
import info.nightscout.androidaps.extensions.durationInMinutes
|
||||||
import info.nightscout.androidaps.extensions.toStringFull
|
import info.nightscout.androidaps.extensions.toStringFull
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.shared.logging.LTag
|
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui
|
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData
|
import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData
|
||||||
|
@ -25,6 +24,8 @@ import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
@ -68,26 +69,6 @@ class DataBroadcastPlugin @Inject constructor(
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ sendData(it) }, fabricPrivacy::logException)
|
.subscribe({ sendData(it) }, fabricPrivacy::logException)
|
||||||
)
|
)
|
||||||
disposable.add(rxBus
|
|
||||||
.toObservable(EventExtendedBolusChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ sendData(it) }, fabricPrivacy::logException)
|
|
||||||
)
|
|
||||||
disposable.add(rxBus
|
|
||||||
.toObservable(EventTempBasalChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ sendData(it) }, fabricPrivacy::logException)
|
|
||||||
)
|
|
||||||
disposable.add(rxBus
|
|
||||||
.toObservable(EventTreatmentChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ sendData(it) }, fabricPrivacy::logException)
|
|
||||||
)
|
|
||||||
disposable.add(rxBus
|
|
||||||
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ sendData(it) }, fabricPrivacy::logException)
|
|
||||||
)
|
|
||||||
disposable.add(rxBus
|
disposable.add(rxBus
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
|
|
|
@ -170,8 +170,7 @@ class NSClientPlugin @Inject constructor(
|
||||||
|
|
||||||
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "Service is connected")
|
aapsLogger.debug(LTag.NSCLIENT, "Service is connected")
|
||||||
val mLocalBinder = service as NSClientService.LocalBinder
|
val mLocalBinder = service as NSClientService.LocalBinder?
|
||||||
@Suppress("UNNECESSARY_SAFE_CALL")
|
|
||||||
nsClientService = mLocalBinder?.serviceInstance // is null when running in roboelectric
|
nsClientService = mLocalBinder?.serviceInstance // is null when running in roboelectric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,42 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview
|
package info.nightscout.androidaps.plugins.general.overview
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.DashPathEffect
|
|
||||||
import android.graphics.Paint
|
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import com.jjoe64.graphview.series.BarGraphSeries
|
import com.jjoe64.graphview.series.BarGraphSeries
|
||||||
import com.jjoe64.graphview.series.DataPoint
|
import com.jjoe64.graphview.series.DataPoint
|
||||||
import com.jjoe64.graphview.series.LineGraphSeries
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
import dagger.android.HasAndroidInjector
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.database.ValueWrapper
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
import info.nightscout.androidaps.database.entities.Bolus
|
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
import info.nightscout.androidaps.extensions.convertedToPercent
|
||||||
import info.nightscout.androidaps.extensions.*
|
import info.nightscout.androidaps.extensions.isInProgress
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.extensions.toStringFull
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.androidaps.extensions.toStringShort
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.androidaps.extensions.valueToUnits
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.FixedLineGraphSeries
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.ceil
|
|
||||||
import kotlin.math.max
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class OverviewData @Inject constructor(
|
class OverviewData @Inject constructor(
|
||||||
private val injector: HasAndroidInjector,
|
|
||||||
private val aapsLogger: AAPSLogger,
|
private val aapsLogger: AAPSLogger,
|
||||||
private val rh: ResourceHelper,
|
private val rh: ResourceHelper,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
|
@ -48,13 +44,7 @@ class OverviewData @Inject constructor(
|
||||||
private val activePlugin: ActivePlugin,
|
private val activePlugin: ActivePlugin,
|
||||||
private val defaultValueHelper: DefaultValueHelper,
|
private val defaultValueHelper: DefaultValueHelper,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val config: Config,
|
private val repository: AppRepository
|
||||||
private val loop: Loop,
|
|
||||||
private val nsDeviceStatus: NSDeviceStatus,
|
|
||||||
private val repository: AppRepository,
|
|
||||||
private val overviewMenus: OverviewMenus,
|
|
||||||
private val iobCobCalculator: IobCobCalculator,
|
|
||||||
private val translator: Translator
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var rangeToDisplay = 6 // for graph
|
var rangeToDisplay = 6 // for graph
|
||||||
|
@ -65,13 +55,6 @@ class OverviewData @Inject constructor(
|
||||||
fun reset() {
|
fun reset() {
|
||||||
pumpStatus = ""
|
pumpStatus = ""
|
||||||
calcProgressPct = 100
|
calcProgressPct = 100
|
||||||
lastBg = null
|
|
||||||
bolusIob = null
|
|
||||||
basalIob = null
|
|
||||||
cobInfo = null
|
|
||||||
lastCarbsTime = 0L
|
|
||||||
temporaryTarget = null
|
|
||||||
lastAutosensData = null
|
|
||||||
bgReadingsArray = ArrayList()
|
bgReadingsArray = ArrayList()
|
||||||
bucketedGraphSeries = PointsWithLabelGraphSeries()
|
bucketedGraphSeries = PointsWithLabelGraphSeries()
|
||||||
bgReadingGraphSeries = PointsWithLabelGraphSeries()
|
bgReadingGraphSeries = PointsWithLabelGraphSeries()
|
||||||
|
@ -128,7 +111,12 @@ class OverviewData @Inject constructor(
|
||||||
* BG
|
* BG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var lastBg: GlucoseValue? = null
|
val lastBg: GlucoseValue?
|
||||||
|
get() =
|
||||||
|
repository.getLastGlucoseValueWrapped().blockingGet().let { gvWrapped ->
|
||||||
|
if (gvWrapped is ValueWrapper.Existing) gvWrapped.value
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
val isLow: Boolean
|
val isLow: Boolean
|
||||||
get() = lastBg?.let { lastBg ->
|
get() = lastBg?.let { lastBg ->
|
||||||
|
@ -165,17 +153,16 @@ class OverviewData @Inject constructor(
|
||||||
* TEMPORARY BASAL
|
* TEMPORARY BASAL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val temporaryBasalText: String
|
fun temporaryBasalText(iobCobCalculator: IobCobCalculator): String =
|
||||||
get() =
|
profileFunction.getProfile()?.let { profile ->
|
||||||
profileFunction.getProfile()?.let { profile ->
|
var temporaryBasal = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())
|
||||||
var temporaryBasal = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())
|
if (temporaryBasal?.isInProgress == false) temporaryBasal = null
|
||||||
if (temporaryBasal?.isInProgress == false) temporaryBasal = null
|
temporaryBasal?.let { "T:" + it.toStringShort() }
|
||||||
temporaryBasal?.let { "T:" + it.toStringShort() }
|
?: rh.gs(R.string.pump_basebasalrate, profile.getBasal())
|
||||||
?: rh.gs(R.string.pump_basebasalrate, profile.getBasal())
|
} ?: rh.gs(R.string.notavailable)
|
||||||
} ?: rh.gs(R.string.notavailable)
|
|
||||||
|
|
||||||
val temporaryBasalDialogText: String
|
fun temporaryBasalDialogText(iobCobCalculator: IobCobCalculator): String =
|
||||||
get() = profileFunction.getProfile()?.let { profile ->
|
profileFunction.getProfile()?.let { profile ->
|
||||||
iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal ->
|
iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal ->
|
||||||
"${rh.gs(R.string.basebasalrate_label)}: ${rh.gs(R.string.pump_basebasalrate, profile.getBasal())}" +
|
"${rh.gs(R.string.basebasalrate_label)}: ${rh.gs(R.string.pump_basebasalrate, profile.getBasal())}" +
|
||||||
"\n" + rh.gs(R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil)
|
"\n" + rh.gs(R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil)
|
||||||
|
@ -183,76 +170,78 @@ class OverviewData @Inject constructor(
|
||||||
?: "${rh.gs(R.string.basebasalrate_label)}: ${rh.gs(R.string.pump_basebasalrate, profile.getBasal())}"
|
?: "${rh.gs(R.string.basebasalrate_label)}: ${rh.gs(R.string.pump_basebasalrate, profile.getBasal())}"
|
||||||
} ?: rh.gs(R.string.notavailable)
|
} ?: rh.gs(R.string.notavailable)
|
||||||
|
|
||||||
val temporaryBasalIcon: Int
|
fun temporaryBasalIcon(iobCobCalculator: IobCobCalculator): Int =
|
||||||
get() =
|
profileFunction.getProfile()?.let { profile ->
|
||||||
profileFunction.getProfile()?.let { profile ->
|
iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal ->
|
||||||
iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal ->
|
val percentRate = temporaryBasal.convertedToPercent(dateUtil.now(), profile)
|
||||||
val percentRate = temporaryBasal.convertedToPercent(dateUtil.now(), profile)
|
when {
|
||||||
when {
|
percentRate > 100 -> R.drawable.ic_cp_basal_tbr_high
|
||||||
percentRate > 100 -> R.drawable.ic_cp_basal_tbr_high
|
percentRate < 100 -> R.drawable.ic_cp_basal_tbr_low
|
||||||
percentRate < 100 -> R.drawable.ic_cp_basal_tbr_low
|
else -> R.drawable.ic_cp_basal_no_tbr
|
||||||
else -> R.drawable.ic_cp_basal_no_tbr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} ?: R.drawable.ic_cp_basal_no_tbr
|
}
|
||||||
|
} ?: R.drawable.ic_cp_basal_no_tbr
|
||||||
|
|
||||||
val temporaryBasalColor: Int
|
// will be removed if a solution of getting the right color for widget is solved
|
||||||
get() = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { rh.gc(R.color.basal) }
|
fun temporaryBasalColor(iobCobCalculator: IobCobCalculator): Int =
|
||||||
?: rh.gc(R.color.defaulttextcolor)
|
iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { rh.gc(R.color.basal) }
|
||||||
|
?: rh.gc(R.color.textAppearancemediumDark)
|
||||||
|
|
||||||
|
fun temporaryBasalColor(context: Context?, iobCobCalculator: IobCobCalculator): Int = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { rh.gac(context , R.attr.basal) }
|
||||||
|
?: rh.gac(context, R.attr.textAppearancemediumColor)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EXTENDED BOLUS
|
* EXTENDED BOLUS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val extendedBolusText: String
|
fun extendedBolusText(iobCobCalculator: IobCobCalculator): String =
|
||||||
get() =
|
iobCobCalculator.getExtendedBolus(dateUtil.now())?.let { extendedBolus ->
|
||||||
iobCobCalculator.getExtendedBolus(dateUtil.now())?.let { extendedBolus ->
|
if (!extendedBolus.isInProgress(dateUtil)) ""
|
||||||
if (!extendedBolus.isInProgress(dateUtil)) ""
|
else if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) rh.gs(R.string.pump_basebasalrate, extendedBolus.rate)
|
||||||
else if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) rh.gs(R.string.pump_basebasalrate, extendedBolus.rate)
|
else ""
|
||||||
else ""
|
} ?: ""
|
||||||
} ?: ""
|
|
||||||
|
|
||||||
val extendedBolusDialogText: String
|
fun extendedBolusDialogText(iobCobCalculator: IobCobCalculator): String =
|
||||||
get() = iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil) ?: ""
|
iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil) ?: ""
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IOB, COB
|
* IOB, COB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var bolusIob: IobTotal? = null
|
fun bolusIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromBolus().round()
|
||||||
var basalIob: IobTotal? = null
|
fun basalIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
||||||
var cobInfo: CobInfo? = null
|
fun cobInfo(iobCobCalculator: IobCobCalculator): CobInfo = iobCobCalculator.getCobInfo(true, "Overview COB")
|
||||||
var lastCarbsTime: Long = 0L
|
|
||||||
|
|
||||||
val iobText: String
|
val lastCarbsTime: Long
|
||||||
get() =
|
get() = repository.getLastCarbsRecordWrapped().blockingGet().let { lastCarbs ->
|
||||||
bolusIob?.let { bolusIob ->
|
if (lastCarbs is ValueWrapper.Existing) lastCarbs.value.timestamp else 0L
|
||||||
basalIob?.let { basalIob ->
|
}
|
||||||
rh.gs(R.string.formatinsulinunits, bolusIob.iob + basalIob.basaliob)
|
|
||||||
} ?: rh.gs(R.string.value_unavailable_short)
|
|
||||||
} ?: rh.gs(R.string.value_unavailable_short)
|
|
||||||
|
|
||||||
val iobDialogText: String
|
fun iobText(iobCobCalculator: IobCobCalculator): String =
|
||||||
get() =
|
rh.gs(R.string.formatinsulinunits, bolusIob(iobCobCalculator).iob + basalIob(iobCobCalculator).basaliob)
|
||||||
bolusIob?.let { bolusIob ->
|
|
||||||
basalIob?.let { basalIob ->
|
fun iobDialogText(iobCobCalculator: IobCobCalculator): String =
|
||||||
rh.gs(R.string.formatinsulinunits, bolusIob.iob + basalIob.basaliob) + "\n" +
|
rh.gs(R.string.formatinsulinunits, bolusIob(iobCobCalculator).iob + basalIob(iobCobCalculator).basaliob) + "\n" +
|
||||||
rh.gs(R.string.bolus) + ": " + rh.gs(R.string.formatinsulinunits, bolusIob.iob) + "\n" +
|
rh.gs(R.string.bolus) + ": " + rh.gs(R.string.formatinsulinunits, bolusIob(iobCobCalculator).iob) + "\n" +
|
||||||
rh.gs(R.string.basal) + ": " + rh.gs(R.string.formatinsulinunits, basalIob.basaliob)
|
rh.gs(R.string.basal) + ": " + rh.gs(R.string.formatinsulinunits, basalIob(iobCobCalculator).basaliob)
|
||||||
} ?: rh.gs(R.string.value_unavailable_short)
|
|
||||||
} ?: rh.gs(R.string.value_unavailable_short)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEMP TARGET
|
* TEMP TARGET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var temporaryTarget: TemporaryTarget? = null
|
val temporaryTarget: TemporaryTarget?
|
||||||
|
get() =
|
||||||
|
repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet().let { tempTarget ->
|
||||||
|
if (tempTarget is ValueWrapper.Existing) tempTarget.value
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SENSITIVITY
|
* SENSITIVITY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var lastAutosensData: AutosensData? = null
|
fun lastAutosensData(iobCobCalculator: IobCobCalculator) = iobCobCalculator.ads.getLastAutosensData("Overview", aapsLogger, dateUtil)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Graphs
|
* Graphs
|
||||||
*/
|
*/
|
||||||
|
@ -312,532 +301,4 @@ class OverviewData @Inject constructor(
|
||||||
val dsMinScale = Scale()
|
val dsMinScale = Scale()
|
||||||
var dsMaxSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
var dsMaxSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
||||||
var dsMinSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
var dsMinSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
@Suppress("SameParameterValue", "UNUSED_PARAMETER")
|
|
||||||
fun prepareBgData(from: String) {
|
|
||||||
// val start = dateUtil.now()
|
|
||||||
maxBgValue = Double.MIN_VALUE
|
|
||||||
bgReadingsArray = repository.compatGetBgReadingsDataFromTime(fromTime, toTime, false).blockingGet()
|
|
||||||
val bgListArray: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
|
||||||
for (bg in bgReadingsArray) {
|
|
||||||
if (bg.timestamp < fromTime || bg.timestamp > toTime) continue
|
|
||||||
if (bg.value > maxBgValue) maxBgValue = bg.value
|
|
||||||
bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh))
|
|
||||||
}
|
|
||||||
bgListArray.sortWith { o1: DataPointWithLabelInterface, o2: DataPointWithLabelInterface -> o1.x.compareTo(o2.x) }
|
|
||||||
bgReadingGraphSeries = PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] })
|
|
||||||
maxBgValue = Profile.fromMgdlToUnits(maxBgValue, profileFunction.getUnits())
|
|
||||||
if (defaultValueHelper.determineHighLine() > maxBgValue) maxBgValue = defaultValueHelper.determineHighLine()
|
|
||||||
maxBgValue = addUpperChartMargin(maxBgValue)
|
|
||||||
// profiler.log(LTag.UI, "prepareBgData() $from", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
@Synchronized
|
|
||||||
fun preparePredictions(from: String) {
|
|
||||||
// val start = dateUtil.now()
|
|
||||||
val apsResult = if (config.APS) loop.lastRun?.constraintsProcessed else nsDeviceStatus.getAPSResult(injector)
|
|
||||||
val predictionsAvailable = if (config.APS) loop.lastRun?.request?.hasPredictions == true else config.NSCLIENT
|
|
||||||
val menuChartSettings = overviewMenus.setting
|
|
||||||
// align to hours
|
|
||||||
val calendar = Calendar.getInstance().also {
|
|
||||||
it.timeInMillis = System.currentTimeMillis()
|
|
||||||
it[Calendar.MILLISECOND] = 0
|
|
||||||
it[Calendar.SECOND] = 0
|
|
||||||
it[Calendar.MINUTE] = 0
|
|
||||||
it.add(Calendar.HOUR, 1)
|
|
||||||
}
|
|
||||||
if (predictionsAvailable && apsResult != null && menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal]) {
|
|
||||||
var predictionHours = (ceil(apsResult.latestPredictionsTime - System.currentTimeMillis().toDouble()) / (60 * 60 * 1000)).toInt()
|
|
||||||
predictionHours = min(2, predictionHours)
|
|
||||||
predictionHours = max(0, predictionHours)
|
|
||||||
val hoursToFetch = rangeToDisplay - predictionHours
|
|
||||||
toTime = calendar.timeInMillis + 100000 // little bit more to avoid wrong rounding - GraphView specific
|
|
||||||
fromTime = toTime - T.hours(hoursToFetch.toLong()).msecs()
|
|
||||||
endTime = toTime + T.hours(predictionHours.toLong()).msecs()
|
|
||||||
} else {
|
|
||||||
toTime = calendar.timeInMillis + 100000 // little bit more to avoid wrong rounding - GraphView specific
|
|
||||||
fromTime = toTime - T.hours(rangeToDisplay.toLong()).msecs()
|
|
||||||
endTime = toTime
|
|
||||||
}
|
|
||||||
|
|
||||||
val bgListArray: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
|
||||||
val predictions: MutableList<GlucoseValueDataPoint>? = apsResult?.predictions
|
|
||||||
?.map { bg -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh) }
|
|
||||||
?.toMutableList()
|
|
||||||
if (predictions != null) {
|
|
||||||
predictions.sortWith { o1: GlucoseValueDataPoint, o2: GlucoseValueDataPoint -> o1.x.compareTo(o2.x) }
|
|
||||||
for (prediction in predictions) if (prediction.data.value >= 40) bgListArray.add(prediction)
|
|
||||||
}
|
|
||||||
predictionsGraphSeries = PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] })
|
|
||||||
// profiler.log(LTag.UI, "preparePredictions() $from", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
@Suppress("SameParameterValue", "UNUSED_PARAMETER")
|
|
||||||
fun prepareBucketedData(from: String) {
|
|
||||||
// val start = dateUtil.now()
|
|
||||||
val bucketedData = iobCobCalculator.ads.getBucketedDataTableCopy() ?: return
|
|
||||||
if (bucketedData.isEmpty()) {
|
|
||||||
aapsLogger.debug("No bucketed data.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val bucketedListArray: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
|
||||||
for (inMemoryGlucoseValue in bucketedData) {
|
|
||||||
if (inMemoryGlucoseValue.timestamp < fromTime || inMemoryGlucoseValue.timestamp > toTime) continue
|
|
||||||
bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, profileFunction, rh))
|
|
||||||
}
|
|
||||||
bucketedListArray.sortWith { o1: DataPointWithLabelInterface, o2: DataPointWithLabelInterface -> o1.x.compareTo(o2.x) }
|
|
||||||
bucketedGraphSeries = PointsWithLabelGraphSeries(Array(bucketedListArray.size) { i -> bucketedListArray[i] })
|
|
||||||
// profiler.log(LTag.UI, "prepareBucketedData() $from", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
@Synchronized
|
|
||||||
fun prepareBasalData(from: String) {
|
|
||||||
// val start = dateUtil.now()
|
|
||||||
maxBasalValueFound = 0.0
|
|
||||||
val baseBasalArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val tempBasalArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val basalLineArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val absoluteBasalLineArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
var lastLineBasal = 0.0
|
|
||||||
var lastAbsoluteLineBasal = -1.0
|
|
||||||
var lastBaseBasal = 0.0
|
|
||||||
var lastTempBasal = 0.0
|
|
||||||
var time = fromTime
|
|
||||||
while (time < toTime) {
|
|
||||||
val profile = profileFunction.getProfile(time)
|
|
||||||
if (profile == null) {
|
|
||||||
time += 60 * 1000L
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
val basalData = iobCobCalculator.getBasalData(profile, time)
|
|
||||||
val baseBasalValue = basalData.basal
|
|
||||||
var absoluteLineValue = baseBasalValue
|
|
||||||
var tempBasalValue = 0.0
|
|
||||||
var basal = 0.0
|
|
||||||
if (basalData.isTempBasalRunning) {
|
|
||||||
tempBasalValue = basalData.tempBasalAbsolute
|
|
||||||
absoluteLineValue = tempBasalValue
|
|
||||||
if (tempBasalValue != lastTempBasal) {
|
|
||||||
tempBasalArray.add(ScaledDataPoint(time, lastTempBasal, basalScale))
|
|
||||||
tempBasalArray.add(ScaledDataPoint(time, tempBasalValue.also { basal = it }, basalScale))
|
|
||||||
}
|
|
||||||
if (lastBaseBasal != 0.0) {
|
|
||||||
baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, basalScale))
|
|
||||||
baseBasalArray.add(ScaledDataPoint(time, 0.0, basalScale))
|
|
||||||
lastBaseBasal = 0.0
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (baseBasalValue != lastBaseBasal) {
|
|
||||||
baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, basalScale))
|
|
||||||
baseBasalArray.add(ScaledDataPoint(time, baseBasalValue.also { basal = it }, basalScale))
|
|
||||||
lastBaseBasal = baseBasalValue
|
|
||||||
}
|
|
||||||
if (lastTempBasal != 0.0) {
|
|
||||||
tempBasalArray.add(ScaledDataPoint(time, lastTempBasal, basalScale))
|
|
||||||
tempBasalArray.add(ScaledDataPoint(time, 0.0, basalScale))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (baseBasalValue != lastLineBasal) {
|
|
||||||
basalLineArray.add(ScaledDataPoint(time, lastLineBasal, basalScale))
|
|
||||||
basalLineArray.add(ScaledDataPoint(time, baseBasalValue, basalScale))
|
|
||||||
}
|
|
||||||
if (absoluteLineValue != lastAbsoluteLineBasal) {
|
|
||||||
absoluteBasalLineArray.add(ScaledDataPoint(time, lastAbsoluteLineBasal, basalScale))
|
|
||||||
absoluteBasalLineArray.add(ScaledDataPoint(time, basal, basalScale))
|
|
||||||
}
|
|
||||||
lastAbsoluteLineBasal = absoluteLineValue
|
|
||||||
lastLineBasal = baseBasalValue
|
|
||||||
lastTempBasal = tempBasalValue
|
|
||||||
maxBasalValueFound = max(maxBasalValueFound, max(tempBasalValue, baseBasalValue))
|
|
||||||
time += 60 * 1000L
|
|
||||||
}
|
|
||||||
|
|
||||||
// final points
|
|
||||||
basalLineArray.add(ScaledDataPoint(toTime, lastLineBasal, basalScale))
|
|
||||||
baseBasalArray.add(ScaledDataPoint(toTime, lastBaseBasal, basalScale))
|
|
||||||
tempBasalArray.add(ScaledDataPoint(toTime, lastTempBasal, basalScale))
|
|
||||||
absoluteBasalLineArray.add(ScaledDataPoint(toTime, lastAbsoluteLineBasal, basalScale))
|
|
||||||
|
|
||||||
// create series
|
|
||||||
baseBasalGraphSeries = LineGraphSeries(Array(baseBasalArray.size) { i -> baseBasalArray[i] }).also {
|
|
||||||
it.isDrawBackground = true
|
|
||||||
it.backgroundColor = rh.gc(R.color.basebasal)
|
|
||||||
it.thickness = 0
|
|
||||||
}
|
|
||||||
tempBasalGraphSeries = LineGraphSeries(Array(tempBasalArray.size) { i -> tempBasalArray[i] }).also {
|
|
||||||
it.isDrawBackground = true
|
|
||||||
it.backgroundColor = rh.gc(R.color.tempbasal)
|
|
||||||
it.thickness = 0
|
|
||||||
}
|
|
||||||
basalLineGraphSeries = LineGraphSeries(Array(basalLineArray.size) { i -> basalLineArray[i] }).also {
|
|
||||||
it.setCustomPaint(Paint().also { paint ->
|
|
||||||
paint.style = Paint.Style.STROKE
|
|
||||||
paint.strokeWidth = rh.getDisplayMetrics().scaledDensity * 2
|
|
||||||
paint.pathEffect = DashPathEffect(floatArrayOf(2f, 4f), 0f)
|
|
||||||
paint.color = rh.gc(R.color.basal)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
absoluteBasalGraphSeries = LineGraphSeries(Array(absoluteBasalLineArray.size) { i -> absoluteBasalLineArray[i] }).also {
|
|
||||||
it.setCustomPaint(Paint().also { absolutePaint ->
|
|
||||||
absolutePaint.style = Paint.Style.STROKE
|
|
||||||
absolutePaint.strokeWidth = rh.getDisplayMetrics().scaledDensity * 2
|
|
||||||
absolutePaint.color = rh.gc(R.color.basal)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// profiler.log(LTag.UI, "prepareBasalData() $from", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
@Synchronized
|
|
||||||
fun prepareTemporaryTargetData(from: String) {
|
|
||||||
// val start = dateUtil.now()
|
|
||||||
val profile = profileFunction.getProfile() ?: return
|
|
||||||
val units = profileFunction.getUnits()
|
|
||||||
var toTime = toTime
|
|
||||||
val targetsSeriesArray: MutableList<DataPoint> = java.util.ArrayList()
|
|
||||||
var lastTarget = -1.0
|
|
||||||
loop.lastRun?.constraintsProcessed?.let { toTime = max(it.latestPredictionsTime, toTime) }
|
|
||||||
var time = fromTime
|
|
||||||
while (time < toTime) {
|
|
||||||
val tt = repository.getTemporaryTargetActiveAt(time).blockingGet()
|
|
||||||
val value: Double = if (tt is ValueWrapper.Existing) {
|
|
||||||
Profile.fromMgdlToUnits(tt.value.target(), units)
|
|
||||||
} else {
|
|
||||||
Profile.fromMgdlToUnits((profile.getTargetLowMgdl(time) + profile.getTargetHighMgdl(time)) / 2, units)
|
|
||||||
}
|
|
||||||
if (lastTarget != value) {
|
|
||||||
if (lastTarget != -1.0) targetsSeriesArray.add(DataPoint(time.toDouble(), lastTarget))
|
|
||||||
targetsSeriesArray.add(DataPoint(time.toDouble(), value))
|
|
||||||
}
|
|
||||||
lastTarget = value
|
|
||||||
time += 5 * 60 * 1000L
|
|
||||||
}
|
|
||||||
// final point
|
|
||||||
targetsSeriesArray.add(DataPoint(toTime.toDouble(), lastTarget))
|
|
||||||
// create series
|
|
||||||
temporaryTargetSeries = LineGraphSeries(Array(targetsSeriesArray.size) { i -> targetsSeriesArray[i] }).also {
|
|
||||||
it.isDrawBackground = false
|
|
||||||
it.color = rh.gc(R.color.tempTargetBackground)
|
|
||||||
it.thickness = 2
|
|
||||||
}
|
|
||||||
// profiler.log(LTag.UI, "prepareTemporaryTargetData() $from", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
@Synchronized
|
|
||||||
fun prepareTreatmentsData(from: String) {
|
|
||||||
// val start = dateUtil.now()
|
|
||||||
maxTreatmentsValue = 0.0
|
|
||||||
val filteredTreatments: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
|
||||||
repository.getBolusesDataFromTimeToTime(fromTime, endTime, true).blockingGet()
|
|
||||||
.map { BolusDataPoint(it, rh, activePlugin, defaultValueHelper) }
|
|
||||||
.filter { it.data.type == Bolus.Type.NORMAL || it.data.type == Bolus.Type.SMB }
|
|
||||||
.forEach {
|
|
||||||
it.y = getNearestBg(it.x.toLong())
|
|
||||||
filteredTreatments.add(it)
|
|
||||||
}
|
|
||||||
repository.getCarbsDataFromTimeToTimeExpanded(fromTime, endTime, true).blockingGet()
|
|
||||||
.map { CarbsDataPoint(it, rh) }
|
|
||||||
.forEach {
|
|
||||||
it.y = getNearestBg(it.x.toLong())
|
|
||||||
filteredTreatments.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProfileSwitch
|
|
||||||
repository.getEffectiveProfileSwitchDataFromTimeToTime(fromTime, endTime, true).blockingGet()
|
|
||||||
.map { EffectiveProfileSwitchDataPoint(it,rh) }
|
|
||||||
.forEach(filteredTreatments::add)
|
|
||||||
|
|
||||||
// OfflineEvent
|
|
||||||
repository.getOfflineEventDataFromTimeToTime(fromTime, endTime, true).blockingGet()
|
|
||||||
.map {
|
|
||||||
TherapyEventDataPoint(
|
|
||||||
TherapyEvent(timestamp = it.timestamp, duration = it.duration, type = TherapyEvent.Type.APS_OFFLINE, glucoseUnit = TherapyEvent.GlucoseUnit.MMOL),
|
|
||||||
rh,
|
|
||||||
profileFunction,
|
|
||||||
translator
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.forEach(filteredTreatments::add)
|
|
||||||
|
|
||||||
// Extended bolus
|
|
||||||
if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
|
|
||||||
repository.getExtendedBolusDataFromTimeToTime(fromTime, endTime, true).blockingGet()
|
|
||||||
.map { ExtendedBolusDataPoint(it, rh) }
|
|
||||||
.filter { it.duration != 0L }
|
|
||||||
.forEach {
|
|
||||||
it.y = getNearestBg(it.x.toLong())
|
|
||||||
filteredTreatments.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Careportal
|
|
||||||
repository.compatGetTherapyEventDataFromToTime(fromTime - T.hours(6).msecs(), endTime).blockingGet()
|
|
||||||
.map { TherapyEventDataPoint(it, rh, profileFunction, translator) }
|
|
||||||
.filterTimeframe(fromTime, endTime)
|
|
||||||
.forEach {
|
|
||||||
if (it.y == 0.0) it.y = getNearestBg(it.x.toLong())
|
|
||||||
filteredTreatments.add(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// increase maxY if a treatment forces it's own height that's higher than a BG value
|
|
||||||
filteredTreatments.map { it.y }
|
|
||||||
.maxOrNull()
|
|
||||||
?.let(::addUpperChartMargin)
|
|
||||||
?.let { maxTreatmentsValue = maxOf(maxTreatmentsValue, it) }
|
|
||||||
|
|
||||||
treatmentsSeries = PointsWithLabelGraphSeries(filteredTreatments.toTypedArray())
|
|
||||||
// profiler.log(LTag.UI, "prepareTreatmentsData() $from", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
@Synchronized
|
|
||||||
fun prepareIobAutosensData(from: String) {
|
|
||||||
// val start = dateUtil.now()
|
|
||||||
val iobArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val absIobArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
maxIobValueFound = Double.MIN_VALUE
|
|
||||||
var lastIob = 0.0
|
|
||||||
var absLastIob = 0.0
|
|
||||||
var time = fromTime
|
|
||||||
|
|
||||||
val minFailOverActiveList: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
|
||||||
val cobArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
maxCobValueFound = Double.MIN_VALUE
|
|
||||||
var lastCob = 0
|
|
||||||
|
|
||||||
val actArrayHist: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val actArrayPrediction: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val now = dateUtil.now().toDouble()
|
|
||||||
maxIAValue = 0.0
|
|
||||||
|
|
||||||
val bgiArrayHist: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val bgiArrayPrediction: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
maxBGIValue = Double.MIN_VALUE
|
|
||||||
|
|
||||||
val devArray: MutableList<OverviewPlugin.DeviationDataPoint> = java.util.ArrayList()
|
|
||||||
maxDevValueFound = Double.MIN_VALUE
|
|
||||||
|
|
||||||
val ratioArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
maxRatioValueFound = 5.0 //even if sens data equals 0 for all the period, minimum scale is between 95% and 105%
|
|
||||||
minRatioValueFound = -5.0
|
|
||||||
|
|
||||||
val dsMaxArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
val dsMinArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
|
||||||
maxFromMaxValueFound = Double.MIN_VALUE
|
|
||||||
maxFromMinValueFound = Double.MIN_VALUE
|
|
||||||
|
|
||||||
val adsData = iobCobCalculator.ads.clone()
|
|
||||||
|
|
||||||
while (time <= toTime) {
|
|
||||||
val profile = profileFunction.getProfile(time)
|
|
||||||
if (profile == null) {
|
|
||||||
time += 5 * 60 * 1000L
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// IOB
|
|
||||||
val iob = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile)
|
|
||||||
val baseBasalIob = iobCobCalculator.calculateAbsoluteIobFromBaseBasals(time)
|
|
||||||
val absIob = IobTotal.combine(iob, baseBasalIob)
|
|
||||||
val autosensData = adsData.getAutosensDataAtTime(time)
|
|
||||||
if (abs(lastIob - iob.iob) > 0.02) {
|
|
||||||
if (abs(lastIob - iob.iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
|
||||||
iobArray.add(ScaledDataPoint(time, iob.iob, iobScale))
|
|
||||||
maxIobValueFound = maxOf(maxIobValueFound, abs(iob.iob))
|
|
||||||
lastIob = iob.iob
|
|
||||||
}
|
|
||||||
if (abs(absLastIob - absIob.iob) > 0.02) {
|
|
||||||
if (abs(absLastIob - absIob.iob) > 0.2) absIobArray.add(ScaledDataPoint(time, absLastIob, iobScale))
|
|
||||||
absIobArray.add(ScaledDataPoint(time, absIob.iob, iobScale))
|
|
||||||
maxIobValueFound = maxOf(maxIobValueFound, abs(absIob.iob))
|
|
||||||
absLastIob = absIob.iob
|
|
||||||
}
|
|
||||||
|
|
||||||
// COB
|
|
||||||
if (autosensData != null) {
|
|
||||||
val cob = autosensData.cob.toInt()
|
|
||||||
if (cob != lastCob) {
|
|
||||||
if (autosensData.carbsFromBolus > 0) cobArray.add(ScaledDataPoint(time, lastCob.toDouble(), cobScale))
|
|
||||||
cobArray.add(ScaledDataPoint(time, cob.toDouble(), cobScale))
|
|
||||||
maxCobValueFound = max(maxCobValueFound, cob.toDouble())
|
|
||||||
lastCob = cob
|
|
||||||
}
|
|
||||||
if (autosensData.failOverToMinAbsorptionRate) {
|
|
||||||
autosensData.scale = cobScale
|
|
||||||
autosensData.chartTime = time
|
|
||||||
minFailOverActiveList.add(autosensData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACTIVITY
|
|
||||||
if (time <= now) actArrayHist.add(ScaledDataPoint(time, iob.activity, actScale))
|
|
||||||
else actArrayPrediction.add(ScaledDataPoint(time, iob.activity, actScale))
|
|
||||||
maxIAValue = max(maxIAValue, abs(iob.activity))
|
|
||||||
|
|
||||||
// BGI
|
|
||||||
val devBgiScale = overviewMenus.isEnabledIn(OverviewMenus.CharType.DEV) == overviewMenus.isEnabledIn(OverviewMenus.CharType.BGI)
|
|
||||||
val deviation = if (devBgiScale) autosensData?.deviation ?: 0.0 else 0.0
|
|
||||||
val bgi: Double = iob.activity * profile.getIsfMgdl(time) * 5.0
|
|
||||||
if (time <= now) bgiArrayHist.add(ScaledDataPoint(time, bgi, bgiScale))
|
|
||||||
else bgiArrayPrediction.add(ScaledDataPoint(time, bgi, bgiScale))
|
|
||||||
maxBGIValue = max(maxBGIValue, max(abs(bgi), deviation))
|
|
||||||
|
|
||||||
// DEVIATIONS
|
|
||||||
if (autosensData != null) {
|
|
||||||
var color = rh.gc(R.color.deviationblack) // "="
|
|
||||||
if (autosensData.type == "" || autosensData.type == "non-meal") {
|
|
||||||
if (autosensData.pastSensitivity == "C") color = rh.gc(R.color.deviationgrey)
|
|
||||||
if (autosensData.pastSensitivity == "+") color = rh.gc(R.color.deviationgreen)
|
|
||||||
if (autosensData.pastSensitivity == "-") color = rh.gc(R.color.deviationred)
|
|
||||||
} else if (autosensData.type == "uam") {
|
|
||||||
color = rh.gc(R.color.uam)
|
|
||||||
} else if (autosensData.type == "csf") {
|
|
||||||
color = rh.gc(R.color.deviationgrey)
|
|
||||||
}
|
|
||||||
devArray.add(OverviewPlugin.DeviationDataPoint(time.toDouble(), autosensData.deviation, color, devScale))
|
|
||||||
maxDevValueFound = maxOf(maxDevValueFound, abs(autosensData.deviation), abs(bgi))
|
|
||||||
}
|
|
||||||
|
|
||||||
// RATIO
|
|
||||||
if (autosensData != null) {
|
|
||||||
ratioArray.add(ScaledDataPoint(time, 100.0 * (autosensData.autosensResult.ratio - 1), ratioScale))
|
|
||||||
maxRatioValueFound = max(maxRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
|
|
||||||
minRatioValueFound = min(minRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEV SLOPE
|
|
||||||
if (autosensData != null) {
|
|
||||||
dsMaxArray.add(ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale))
|
|
||||||
dsMinArray.add(ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale))
|
|
||||||
maxFromMaxValueFound = max(maxFromMaxValueFound, abs(autosensData.slopeFromMaxDeviation))
|
|
||||||
maxFromMinValueFound = max(maxFromMinValueFound, abs(autosensData.slopeFromMinDeviation))
|
|
||||||
}
|
|
||||||
|
|
||||||
time += 5 * 60 * 1000L
|
|
||||||
}
|
|
||||||
// IOB
|
|
||||||
iobSeries = FixedLineGraphSeries(Array(iobArray.size) { i -> iobArray[i] }).also {
|
|
||||||
it.isDrawBackground = true
|
|
||||||
it.backgroundColor = -0x7f000001 and rh.gc(R.color.iob) //50%
|
|
||||||
it.color = rh.gc(R.color.iob)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
absIobSeries = FixedLineGraphSeries(Array(absIobArray.size) { i -> absIobArray[i] }).also {
|
|
||||||
it.isDrawBackground = true
|
|
||||||
it.backgroundColor = -0x7f000001 and rh.gc(R.color.iob) //50%
|
|
||||||
it.color = rh.gc(R.color.iob)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overviewMenus.setting[0][OverviewMenus.CharType.PRE.ordinal]) {
|
|
||||||
val autosensData = adsData.getLastAutosensData("GraphData", aapsLogger, dateUtil)
|
|
||||||
val lastAutosensResult = autosensData?.autosensResult ?: AutosensResult()
|
|
||||||
val isTempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
|
|
||||||
val iobPrediction: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
|
||||||
val iobPredictionArray = iobCobCalculator.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
|
|
||||||
for (i in iobPredictionArray) {
|
|
||||||
iobPrediction.add(i.setColor(rh.gc(R.color.iobPredAS)))
|
|
||||||
maxIobValueFound = max(maxIobValueFound, abs(i.iob))
|
|
||||||
}
|
|
||||||
iobPredictions1Series = PointsWithLabelGraphSeries(Array(iobPrediction.size) { i -> iobPrediction[i] })
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "IOB prediction for AS=" + DecimalFormatter.to2Decimal(lastAutosensResult.ratio) + ": " + iobCobCalculator.iobArrayToString(iobPredictionArray))
|
|
||||||
/*
|
|
||||||
val iobPrediction2: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
|
||||||
val iobPredictionArray2 = iobCobCalculator.calculateIobArrayForSMB(AutosensResult(), SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
|
|
||||||
for (i in iobPredictionArray2) {
|
|
||||||
iobPrediction2.add(i.setColor(rh.gc(R.color.iobPred)))
|
|
||||||
maxIobValueFound = max(maxIobValueFound, abs(i.iob))
|
|
||||||
}
|
|
||||||
iobPredictions2Series = PointsWithLabelGraphSeries(Array(iobPrediction2.size) { i -> iobPrediction2[i] })
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "IOB prediction for AS=" + DecimalFormatter.to2Decimal(1.0) + ": " + iobCobCalculator.iobArrayToString(iobPredictionArray2))
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
iobPredictions1Series = PointsWithLabelGraphSeries()
|
|
||||||
//iobPredictions2Series = PointsWithLabelGraphSeries()
|
|
||||||
}
|
|
||||||
|
|
||||||
// COB
|
|
||||||
cobSeries = FixedLineGraphSeries(Array(cobArray.size) { i -> cobArray[i] }).also {
|
|
||||||
it.isDrawBackground = true
|
|
||||||
it.backgroundColor = -0x7f000001 and rh.gc(R.color.cob) //50%
|
|
||||||
it.color = rh.gc(R.color.cob)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
cobMinFailOverSeries = PointsWithLabelGraphSeries(Array(minFailOverActiveList.size) { i -> minFailOverActiveList[i] })
|
|
||||||
|
|
||||||
// ACTIVITY
|
|
||||||
activitySeries = FixedLineGraphSeries(Array(actArrayHist.size) { i -> actArrayHist[i] }).also {
|
|
||||||
it.isDrawBackground = false
|
|
||||||
it.color = rh.gc(R.color.activity)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
activityPredictionSeries = FixedLineGraphSeries(Array(actArrayPrediction.size) { i -> actArrayPrediction[i] }).also {
|
|
||||||
it.setCustomPaint(Paint().also { paint ->
|
|
||||||
paint.style = Paint.Style.STROKE
|
|
||||||
paint.strokeWidth = 3f
|
|
||||||
paint.pathEffect = DashPathEffect(floatArrayOf(4f, 4f), 0f)
|
|
||||||
paint.color = rh.gc(R.color.activity)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// BGI
|
|
||||||
minusBgiSeries = FixedLineGraphSeries(Array(bgiArrayHist.size) { i -> bgiArrayHist[i] }).also {
|
|
||||||
it.isDrawBackground = false
|
|
||||||
it.color = rh.gc(R.color.bgi)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
minusBgiHistSeries = FixedLineGraphSeries(Array(bgiArrayPrediction.size) { i -> bgiArrayPrediction[i] }).also {
|
|
||||||
it.setCustomPaint(Paint().also { paint ->
|
|
||||||
paint.style = Paint.Style.STROKE
|
|
||||||
paint.strokeWidth = 3f
|
|
||||||
paint.pathEffect = DashPathEffect(floatArrayOf(4f, 4f), 0f)
|
|
||||||
paint.color = rh.gc(R.color.bgi)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEVIATIONS
|
|
||||||
deviationsSeries = BarGraphSeries(Array(devArray.size) { i -> devArray[i] }).also {
|
|
||||||
it.setValueDependentColor { data: OverviewPlugin.DeviationDataPoint -> data.color }
|
|
||||||
}
|
|
||||||
|
|
||||||
// RATIO
|
|
||||||
ratioSeries = LineGraphSeries(Array(ratioArray.size) { i -> ratioArray[i] }).also {
|
|
||||||
it.color = rh.gc(R.color.ratio)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEV SLOPE
|
|
||||||
dsMaxSeries = LineGraphSeries(Array(dsMaxArray.size) { i -> dsMaxArray[i] }).also {
|
|
||||||
it.color = rh.gc(R.color.devslopepos)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
dsMinSeries = LineGraphSeries(Array(dsMinArray.size) { i -> dsMinArray[i] }).also {
|
|
||||||
it.color = rh.gc(R.color.devslopeneg)
|
|
||||||
it.thickness = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
// profiler.log(LTag.UI, "prepareIobAutosensData() $from", start)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addUpperChartMargin(maxBgValue: Double) =
|
|
||||||
if (profileFunction.getUnits() == GlucoseUnit.MGDL) Round.roundTo(maxBgValue, 40.0) + 80 else Round.roundTo(maxBgValue, 2.0) + 4
|
|
||||||
|
|
||||||
private fun getNearestBg(date: Long): Double {
|
|
||||||
bgReadingsArray.let { bgReadingsArray ->
|
|
||||||
for (reading in bgReadingsArray) {
|
|
||||||
if (reading.timestamp > date) continue
|
|
||||||
return Profile.fromMgdlToUnits(reading.value, profileFunction.getUnits())
|
|
||||||
}
|
|
||||||
return if (bgReadingsArray.isNotEmpty()) Profile.fromMgdlToUnits(bgReadingsArray[0].value, profileFunction.getUnits())
|
|
||||||
else Profile.fromMgdlToUnits(100.0, profileFunction.getUnits())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <E : DataPointWithLabelInterface> List<E>.filterTimeframe(fromTime: Long, endTime: Long): List<E> =
|
|
||||||
filter { it.x + it.duration >= fromTime && it.x <= endTime }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,13 +36,9 @@ import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||||
import info.nightscout.androidaps.database.interfaces.end
|
import info.nightscout.androidaps.database.interfaces.end
|
||||||
import info.nightscout.androidaps.databinding.OverviewFragmentBinding
|
import info.nightscout.androidaps.databinding.OverviewFragmentBinding
|
||||||
import info.nightscout.androidaps.dialogs.*
|
import info.nightscout.androidaps.dialogs.*
|
||||||
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange
|
import info.nightscout.androidaps.events.*
|
||||||
import info.nightscout.androidaps.events.EventInitializationChanged
|
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
|
||||||
import info.nightscout.androidaps.events.EventPumpStatusChanged
|
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview
|
|
||||||
import info.nightscout.androidaps.extensions.directionToIcon
|
import info.nightscout.androidaps.extensions.directionToIcon
|
||||||
import info.nightscout.androidaps.extensions.isInProgress
|
import info.nightscout.androidaps.extensions.runOnUiThread
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.extensions.valueToUnitsString
|
import info.nightscout.androidaps.extensions.valueToUnitsString
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
|
@ -188,10 +184,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
overviewData.rangeToDisplay += 6
|
overviewData.rangeToDisplay += 6
|
||||||
overviewData.rangeToDisplay = if (overviewData.rangeToDisplay > 24) 6 else overviewData.rangeToDisplay
|
overviewData.rangeToDisplay = if (overviewData.rangeToDisplay > 24) 6 else overviewData.rangeToDisplay
|
||||||
sp.putInt(R.string.key_rangetodisplay, overviewData.rangeToDisplay)
|
sp.putInt(R.string.key_rangetodisplay, overviewData.rangeToDisplay)
|
||||||
overviewData.initRange()
|
|
||||||
overviewData.prepareBucketedData("EventBucketedDataCreated")
|
|
||||||
overviewData.prepareBgData("EventBucketedDataCreated")
|
|
||||||
updateGraph("rangeChange")
|
|
||||||
rxBus.send(EventPreferenceChange(rh, R.string.key_rangetodisplay))
|
rxBus.send(EventPreferenceChange(rh, R.string.key_rangetodisplay))
|
||||||
sp.putBoolean(R.string.key_objectiveusescale, true)
|
sp.putBoolean(R.string.key_objectiveusescale, true)
|
||||||
false
|
false
|
||||||
|
@ -227,113 +219,106 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
|
||||||
.toObservable(EventUpdateOverviewTime::class.java)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateTime(it.from) }, fabricPrivacy::logException)
|
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
disposable += activePlugin.activeOverview.overviewBus
|
||||||
.toObservable(EventUpdateOverviewCalcProgress::class.java)
|
.toObservable(EventUpdateOverviewCalcProgress::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updateCalcProgress(it.from) }, fabricPrivacy::logException)
|
.subscribe({ updateCalcProgress() }, fabricPrivacy::logException)
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
|
||||||
.toObservable(EventUpdateOverviewProfile::class.java)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateProfile(it.from) }, fabricPrivacy::logException)
|
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
|
||||||
.toObservable(EventUpdateOverviewTemporaryBasal::class.java)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateTemporaryBasal(it.from) }, fabricPrivacy::logException)
|
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
|
||||||
.toObservable(EventUpdateOverviewExtendedBolus::class.java)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateExtendedBolus(it.from) }, fabricPrivacy::logException)
|
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
|
||||||
.toObservable(EventUpdateOverviewTemporaryTarget::class.java)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateTemporaryTarget(it.from) }, fabricPrivacy::logException)
|
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
|
||||||
.toObservable(EventUpdateOverviewBg::class.java)
|
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateBg(it.from) }, fabricPrivacy::logException)
|
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
disposable += activePlugin.activeOverview.overviewBus
|
||||||
.toObservable(EventUpdateOverviewIobCob::class.java)
|
.toObservable(EventUpdateOverviewIobCob::class.java)
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updateIobCob(it.from) }, fabricPrivacy::logException)
|
.subscribe({ updateIobCob() }, fabricPrivacy::logException)
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
disposable += activePlugin.activeOverview.overviewBus
|
||||||
.toObservable(EventUpdateOverviewSensitivity::class.java)
|
.toObservable(EventUpdateOverviewSensitivity::class.java)
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updateSensitivity(it.from) }, fabricPrivacy::logException)
|
.subscribe({ updateSensitivity() }, fabricPrivacy::logException)
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
disposable += activePlugin.activeOverview.overviewBus
|
||||||
.toObservable(EventUpdateOverviewGraph::class.java)
|
.toObservable(EventUpdateOverviewGraph::class.java)
|
||||||
.debounce(1L, TimeUnit.SECONDS)
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updateGraph(it.from) }, fabricPrivacy::logException)
|
.subscribe({ updateGraph() }, fabricPrivacy::logException)
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
disposable += activePlugin.activeOverview.overviewBus
|
||||||
.toObservable(EventUpdateOverviewPumpStatus::class.java)
|
.toObservable(EventUpdateOverviewPumpStatus::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updatePumpStatus(it.from) }, fabricPrivacy::logException)
|
.subscribe({ updatePumpStatus() }, fabricPrivacy::logException)
|
||||||
disposable += activePlugin.activeOverview.overviewBus
|
disposable += activePlugin.activeOverview.overviewBus
|
||||||
.toObservable(EventUpdateOverviewNotification::class.java)
|
.toObservable(EventUpdateOverviewNotification::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updateNotification(it.from) }, fabricPrivacy::logException)
|
.subscribe({ updateNotification() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventNewBG::class.java)
|
||||||
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateBg() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventRefreshOverview::class.java)
|
.toObservable(EventRefreshOverview::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
if (it.now) overviewPlugin.refreshLoop(it.from)
|
if (it.now) refreshAll()
|
||||||
else scheduleUpdateGUI(it.from)
|
else scheduleUpdateGUI()
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventAcceptOpenLoopChange::class.java)
|
.toObservable(EventAcceptOpenLoopChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ scheduleUpdateGUI("EventAcceptOpenLoopChange") }, fabricPrivacy::logException)
|
.subscribe({ scheduleUpdateGUI() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventInitializationChanged::class.java)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateTime("EventInitializationChanged") }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventPreferenceChange::class.java)
|
.toObservable(EventPreferenceChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ scheduleUpdateGUI("EventPreferenceChange") }, fabricPrivacy::logException)
|
.subscribe({ scheduleUpdateGUI() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNewOpenLoopNotification::class.java)
|
.toObservable(EventNewOpenLoopNotification::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ scheduleUpdateGUI("EventNewOpenLoopNotification") }, fabricPrivacy::logException)
|
.subscribe({ scheduleUpdateGUI() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventPumpStatusChanged::class.java)
|
.toObservable(EventPumpStatusChanged::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.delay(30, TimeUnit.MILLISECONDS, aapsSchedulers.main)
|
.delay(30, TimeUnit.MILLISECONDS, aapsSchedulers.main)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
overviewData.pumpStatus = it.getStatus(rh)
|
overviewData.pumpStatus = it.getStatus(rh)
|
||||||
updatePumpStatus("EventPumpStatusChanged")
|
updatePumpStatus()
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateProfile() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventTempTargetChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateTemporaryTarget() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventExtendedBolusChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateExtendedBolus() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventTempBasalChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe({ updateTemporaryBasal() }, fabricPrivacy::logException)
|
||||||
|
|
||||||
refreshLoop = Runnable {
|
refreshLoop = Runnable {
|
||||||
overviewPlugin.refreshLoop("refreshLoop")
|
refreshAll()
|
||||||
handler.postDelayed(refreshLoop, 60 * 1000L)
|
handler.postDelayed(refreshLoop, 60 * 1000L)
|
||||||
}
|
}
|
||||||
handler.postDelayed(refreshLoop, 60 * 1000L)
|
handler.postDelayed(refreshLoop, 60 * 1000L)
|
||||||
|
|
||||||
updateTime("onResume")
|
refreshAll()
|
||||||
updateCalcProgress("onResume")
|
updatePumpStatus()
|
||||||
updateProfile("onResume")
|
updateCalcProgress()
|
||||||
updateTemporaryBasal("onResume")
|
}
|
||||||
updateExtendedBolus("onResume")
|
|
||||||
updateTemporaryTarget("onResume")
|
fun refreshAll() {
|
||||||
updateBg("onResume")
|
runOnUiThread {
|
||||||
updateIobCob("onResume")
|
updateBg()
|
||||||
updateSensitivity("onResume")
|
updateTime()
|
||||||
updateGraph("onResume")
|
updateProfile()
|
||||||
updatePumpStatus("onResume")
|
updateTemporaryBasal()
|
||||||
updateNotification("onResume")
|
updateExtendedBolus()
|
||||||
|
updateTemporaryTarget()
|
||||||
|
updateIobCob()
|
||||||
|
updateSensitivity()
|
||||||
|
updateGraph()
|
||||||
|
updateNotification()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -563,14 +548,14 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_byoda), null, null)
|
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_byoda), null, null)
|
||||||
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) {
|
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) {
|
||||||
drawable?.mutate()
|
drawable?.mutate()
|
||||||
drawable?.colorFilter = PorterDuffColorFilter(rh.gac( context,R.attr.cgmdexColor ), PorterDuff.Mode.SRC_IN)
|
drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmdexColor), PorterDuff.Mode.SRC_IN)
|
||||||
}
|
}
|
||||||
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmdexColor))
|
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmdexColor))
|
||||||
} else if (xDripIsBgSource) {
|
} else if (xDripIsBgSource) {
|
||||||
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_xdrip), null, null)
|
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_xdrip), null, null)
|
||||||
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) {
|
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) {
|
||||||
drawable?.mutate()
|
drawable?.mutate()
|
||||||
drawable?.colorFilter = PorterDuffColorFilter(rh.gac( context,R.attr.cgmxdripColor ), PorterDuff.Mode.SRC_IN)
|
drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmxdripColor), PorterDuff.Mode.SRC_IN)
|
||||||
}
|
}
|
||||||
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmxdripColor))
|
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmxdripColor))
|
||||||
}
|
}
|
||||||
|
@ -752,11 +737,11 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
|
|
||||||
var task: Runnable? = null
|
var task: Runnable? = null
|
||||||
|
|
||||||
private fun scheduleUpdateGUI(from: String) {
|
private fun scheduleUpdateGUI() {
|
||||||
class UpdateRunnable : Runnable {
|
class UpdateRunnable : Runnable {
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
overviewPlugin.refreshLoop(from)
|
refreshAll()
|
||||||
task = null
|
task = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -766,8 +751,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@Suppress("UNUSED_PARAMETER")
|
fun updateBg() {
|
||||||
fun updateBg(from: String) {
|
|
||||||
val units = profileFunction.getUnits()
|
val units = profileFunction.getUnits()
|
||||||
binding.infoLayout.bg.text = overviewData.lastBg?.valueToUnitsString(units)
|
binding.infoLayout.bg.text = overviewData.lastBg?.valueToUnitsString(units)
|
||||||
?: rh.gs(R.string.notavailable)
|
?: rh.gs(R.string.notavailable)
|
||||||
|
@ -816,8 +800,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
fun updateProfile() {
|
||||||
fun updateProfile(from: String) {
|
|
||||||
val profileBackgroundColor =
|
val profileBackgroundColor =
|
||||||
profileFunction.getProfile()?.let {
|
profileFunction.getProfile()?.let {
|
||||||
if (it is ProfileSealed.EPS) {
|
if (it is ProfileSealed.EPS) {
|
||||||
|
@ -849,28 +832,25 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
binding.activeProfile.setTextColor(profileTextColor)
|
binding.activeProfile.setTextColor(profileTextColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
private fun updateTemporaryBasal() {
|
||||||
fun updateTemporaryBasal(from: String) {
|
binding.infoLayout.baseBasal.text = overviewData.temporaryBasalText(iobCobCalculator)
|
||||||
binding.infoLayout.baseBasal.text = overviewData.temporaryBasalText
|
binding.infoLayout.baseBasal.setTextColor(overviewData.temporaryBasalColor(context, iobCobCalculator))
|
||||||
binding.infoLayout.baseBasal.setTextColor(overviewData.temporaryBasalColor)
|
binding.infoLayout.baseBasalIcon.setImageResource(overviewData.temporaryBasalIcon(iobCobCalculator))
|
||||||
binding.infoLayout.baseBasalIcon.setImageResource(overviewData.temporaryBasalIcon)
|
|
||||||
binding.infoLayout.basalLayout.setOnClickListener {
|
binding.infoLayout.basalLayout.setOnClickListener {
|
||||||
activity?.let { OKDialog.show(it, rh.gs(R.string.basal), overviewData.temporaryBasalDialogText) }
|
activity?.let { OKDialog.show(it, rh.gs(R.string.basal), overviewData.temporaryBasalDialogText(iobCobCalculator)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
private fun updateExtendedBolus() {
|
||||||
fun updateExtendedBolus(from: String) {
|
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
binding.infoLayout.extendedBolus.text = overviewData.extendedBolusText
|
binding.infoLayout.extendedBolus.text = overviewData.extendedBolusText(iobCobCalculator)
|
||||||
binding.infoLayout.extendedLayout.setOnClickListener {
|
binding.infoLayout.extendedLayout.setOnClickListener {
|
||||||
activity?.let { OKDialog.show(it, rh.gs(R.string.extended_bolus), overviewData.extendedBolusDialogText) }
|
activity?.let { OKDialog.show(it, rh.gs(R.string.extended_bolus), overviewData.extendedBolusDialogText(iobCobCalculator)) }
|
||||||
}
|
}
|
||||||
binding.infoLayout.extendedLayout.visibility = (iobCobCalculator.getExtendedBolus(dateUtil.now()) != null && !pump.isFakingTempsByExtendedBoluses).toVisibility()
|
binding.infoLayout.extendedLayout.visibility = (iobCobCalculator.getExtendedBolus(dateUtil.now()) != null && !pump.isFakingTempsByExtendedBoluses).toVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
fun updateTime() {
|
||||||
fun updateTime(from: String) {
|
|
||||||
binding.infoLayout.time.text = dateUtil.timeString(dateUtil.now())
|
binding.infoLayout.time.text = dateUtil.timeString(dateUtil.now())
|
||||||
// Status lights
|
// Status lights
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
|
@ -901,14 +881,13 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
processAps()
|
processAps()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
fun updateIobCob() {
|
||||||
fun updateIobCob(from: String) {
|
binding.infoLayout.iob.text = overviewData.iobText(iobCobCalculator)
|
||||||
binding.infoLayout.iob.text = overviewData.iobText
|
|
||||||
binding.infoLayout.iobLayout.setOnClickListener {
|
binding.infoLayout.iobLayout.setOnClickListener {
|
||||||
activity?.let { OKDialog.show(it, rh.gs(R.string.iob), overviewData.iobDialogText) }
|
activity?.let { OKDialog.show(it, rh.gs(R.string.iob), overviewData.iobDialogText(iobCobCalculator)) }
|
||||||
}
|
}
|
||||||
// cob
|
// cob
|
||||||
var cobText = overviewData.cobInfo?.displayText(rh, dateUtil, buildHelper.isEngineeringMode()) ?: rh.gs(R.string.value_unavailable_short)
|
var cobText = overviewData.cobInfo(iobCobCalculator).displayText(rh, dateUtil, buildHelper.isEngineeringMode()) ?: rh.gs(R.string.value_unavailable_short)
|
||||||
|
|
||||||
val constraintsProcessed = loop.lastRun?.constraintsProcessed
|
val constraintsProcessed = loop.lastRun?.constraintsProcessed
|
||||||
val lastRun = loop.lastRun
|
val lastRun = loop.lastRun
|
||||||
|
@ -929,10 +908,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@Suppress("UNUSED_PARAMETER")
|
fun updateTemporaryTarget() {
|
||||||
fun updateTemporaryTarget(from: String) {
|
|
||||||
val units = profileFunction.getUnits()
|
val units = profileFunction.getUnits()
|
||||||
if (overviewData.temporaryTarget?.isInProgress(dateUtil) == false) overviewData.temporaryTarget = null
|
|
||||||
val tempTarget = overviewData.temporaryTarget
|
val tempTarget = overviewData.temporaryTarget
|
||||||
if (tempTarget != null) {
|
if (tempTarget != null) {
|
||||||
binding.tempTarget.setTextColor(rh.gac(context, R.attr.ribbonTextWarningColor))
|
binding.tempTarget.setTextColor(rh.gac(context, R.attr.ribbonTextWarningColor))
|
||||||
|
@ -957,8 +934,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
private fun updateGraph() {
|
||||||
fun updateGraph(from: String) {
|
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
val graphData = GraphData(injector, binding.graphsLayout.bgGraph, overviewData)
|
val graphData = GraphData(injector, binding.graphsLayout.bgGraph, overviewData)
|
||||||
val menuChartSettings = overviewMenus.setting
|
val menuChartSettings = overviewMenus.setting
|
||||||
|
@ -1036,14 +1012,12 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
private fun updateCalcProgress() {
|
||||||
fun updateCalcProgress(from: String) {
|
|
||||||
binding.progressBar.progress = overviewData.calcProgressPct
|
binding.progressBar.progress = overviewData.calcProgressPct
|
||||||
binding.progressBar.visibility = (overviewData.calcProgressPct != 100).toVisibility()
|
binding.progressBar.visibility = (overviewData.calcProgressPct != 100).toVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
private fun updateSensitivity() {
|
||||||
fun updateSensitivity(from: String) {
|
|
||||||
if (sp.getBoolean(R.string.key_openapsama_useautosens, false) && constraintChecker.isAutosensModeEnabled().value()) {
|
if (sp.getBoolean(R.string.key_openapsama_useautosens, false) && constraintChecker.isAutosensModeEnabled().value()) {
|
||||||
binding.infoLayout.sensitivityIcon.setImageResource(R.drawable.ic_swap_vert_black_48dp_green)
|
binding.infoLayout.sensitivityIcon.setImageResource(R.drawable.ic_swap_vert_black_48dp_green)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1051,20 +1025,18 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.infoLayout.sensitivity.text =
|
binding.infoLayout.sensitivity.text =
|
||||||
overviewData.lastAutosensData?.let { autosensData ->
|
overviewData.lastAutosensData(iobCobCalculator)?.let { autosensData ->
|
||||||
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
|
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
|
||||||
} ?: ""
|
} ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
private fun updatePumpStatus() {
|
||||||
fun updatePumpStatus(from: String) {
|
|
||||||
val status = overviewData.pumpStatus
|
val status = overviewData.pumpStatus
|
||||||
binding.pumpStatus.text = status
|
binding.pumpStatus.text = status
|
||||||
binding.pumpStatusLayout.visibility = (status != "").toVisibility()
|
binding.pumpStatusLayout.visibility = (status != "").toVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
private fun updateNotification() {
|
||||||
fun updateNotification(from: String) {
|
|
||||||
binding.notifications.let { notificationStore.updateNotifications(it) }
|
binding.notifications.let { notificationStore.updateNotifications(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,25 +4,26 @@ import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.SwitchPreference
|
import androidx.preference.SwitchPreference
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.events.EventPumpStatusChanged
|
||||||
import info.nightscout.androidaps.database.ValueWrapper
|
|
||||||
import info.nightscout.androidaps.events.*
|
|
||||||
import info.nightscout.androidaps.extensions.*
|
import info.nightscout.androidaps.extensions.*
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.androidaps.interfaces.Overview
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventLoopInvoked
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.*
|
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.EventUpdateOverviewCalcProgress
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewNotification
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
|
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
@ -41,9 +42,6 @@ class OverviewPlugin @Inject constructor(
|
||||||
private val aapsSchedulers: AapsSchedulers,
|
private val aapsSchedulers: AapsSchedulers,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
private val config: Config,
|
private val config: Config,
|
||||||
private val dateUtil: DateUtil,
|
|
||||||
private val iobCobCalculator: IobCobCalculator,
|
|
||||||
private val repository: AppRepository,
|
|
||||||
private val overviewData: OverviewData,
|
private val overviewData: OverviewData,
|
||||||
private val overviewMenus: OverviewMenus
|
private val overviewMenus: OverviewMenus
|
||||||
) : PluginBase(
|
) : PluginBase(
|
||||||
|
@ -89,62 +87,9 @@ class OverviewPlugin @Inject constructor(
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventIobCalculationProgress::class.java)
|
.toObservable(EventIobCalculationProgress::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ overviewData.calcProgressPct = it.progressPct; overviewBus.send(EventUpdateOverviewCalcProgress("EventIobCalculationProgress")) }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTempBasalChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ overviewBus.send(EventUpdateOverviewTemporaryBasal("EventTempBasalChange")) }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventExtendedBolusChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ overviewBus.send(EventUpdateOverviewExtendedBolus("EventExtendedBolusChange")) }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventNewBG::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ loadBg("EventNewBG") }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTempTargetChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ loadTemporaryTarget("EventTempTargetChange") }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({
|
.subscribe({
|
||||||
loadIobCobResults("EventTreatmentChange")
|
overviewData.calcProgressPct = it.pass.finalPercent(it.progressPct)
|
||||||
overviewData.prepareTreatmentsData("EventTreatmentChange")
|
overviewBus.send(EventUpdateOverviewCalcProgress("EventIobCalculationProgress"))
|
||||||
overviewBus.send(EventUpdateOverviewGraph("EventTreatmentChange"))
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTherapyEventChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({
|
|
||||||
overviewData.prepareTreatmentsData("EventTherapyEventChange")
|
|
||||||
overviewBus.send(EventUpdateOverviewGraph("EventTherapyEventChange"))
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventBucketedDataCreated::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({
|
|
||||||
overviewData.prepareBucketedData("EventBucketedDataCreated")
|
|
||||||
overviewData.prepareBgData("EventBucketedDataCreated")
|
|
||||||
overviewBus.send(EventUpdateOverviewGraph("EventBucketedDataCreated"))
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventLoopInvoked::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ overviewData.preparePredictions("EventLoopInvoked") }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({
|
|
||||||
loadProfile("EventEffectiveProfileSwitchChanged")
|
|
||||||
overviewData.prepareBasalData("EventEffectiveProfileSwitchChanged")
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({
|
|
||||||
if (it.cause !is EventCustomCalculationFinished) refreshLoop("EventAutosensCalculationFinished")
|
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventPumpStatusChanged::class.java)
|
.toObservable(EventPumpStatusChanged::class.java)
|
||||||
|
@ -152,20 +97,7 @@ class OverviewPlugin @Inject constructor(
|
||||||
.subscribe({
|
.subscribe({
|
||||||
overviewData.pumpStatus = it.getStatus(rh)
|
overviewData.pumpStatus = it.getStatus(rh)
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventPreferenceChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ event ->
|
|
||||||
if (event.isChanged(rh, R.string.key_units)) {
|
|
||||||
overviewData.reset()
|
|
||||||
overviewData.prepareBucketedData("EventBucketedDataCreated")
|
|
||||||
overviewData.prepareBgData("EventBucketedDataCreated")
|
|
||||||
overviewBus.send(EventUpdateOverviewGraph("EventBucketedDataCreated"))
|
|
||||||
loadAll("EventPreferenceChange")
|
|
||||||
}
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
|
|
||||||
Thread { loadAll("onResume") }.start()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
|
@ -243,7 +175,7 @@ class OverviewPlugin @Inject constructor(
|
||||||
.storeDouble(R.string.key_statuslights_bat_critical, sp, rh)
|
.storeDouble(R.string.key_statuslights_bat_critical, sp, rh)
|
||||||
.storeInt(R.string.key_boluswizard_percentage, sp, rh)
|
.storeInt(R.string.key_boluswizard_percentage, sp, rh)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
@Volatile
|
@Volatile
|
||||||
var runningRefresh = false
|
var runningRefresh = false
|
||||||
override fun refreshLoop(from: String) {
|
override fun refreshLoop(from: String) {
|
||||||
|
@ -284,38 +216,5 @@ class OverviewPlugin @Inject constructor(
|
||||||
overviewBus.send(EventUpdateOverviewGraph(from))
|
overviewBus.send(EventUpdateOverviewGraph(from))
|
||||||
aapsLogger.debug(LTag.UI, "loadAll finished")
|
aapsLogger.debug(LTag.UI, "loadAll finished")
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
private fun loadProfile(from: String) {
|
|
||||||
overviewBus.send(EventUpdateOverviewProfile(from))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadTemporaryTarget(from: String) {
|
|
||||||
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
|
||||||
if (tempTarget is ValueWrapper.Existing) overviewData.temporaryTarget = tempTarget.value
|
|
||||||
else overviewData.temporaryTarget = null
|
|
||||||
overviewBus.send(EventUpdateOverviewTemporaryTarget(from))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadAsData(from: String) {
|
|
||||||
overviewData.lastAutosensData = iobCobCalculator.ads.getLastAutosensData("Overview", aapsLogger, dateUtil)
|
|
||||||
overviewBus.send(EventUpdateOverviewSensitivity(from))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadBg(from: String) {
|
|
||||||
val gvWrapped = repository.getLastGlucoseValueWrapped().blockingGet()
|
|
||||||
if (gvWrapped is ValueWrapper.Existing) overviewData.lastBg = gvWrapped.value
|
|
||||||
else overviewData.lastBg = null
|
|
||||||
overviewBus.send(EventUpdateOverviewBg(from))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadIobCobResults(from: String) {
|
|
||||||
overviewData.bolusIob = iobCobCalculator.calculateIobFromBolus().round()
|
|
||||||
overviewData.basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
|
||||||
overviewData.cobInfo = iobCobCalculator.getCobInfo(true, "Overview COB")
|
|
||||||
val lastCarbs = repository.getLastCarbsRecordWrapped().blockingGet()
|
|
||||||
overviewData.lastCarbsTime = if (lastCarbs is ValueWrapper.Existing) lastCarbs.value.timestamp else 0L
|
|
||||||
|
|
||||||
overviewBus.send(EventUpdateOverviewIobCob(from))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.events
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventUpdateOverviewBg(val from: String) : Event()
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.events
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventUpdateOverviewExtendedBolus(val from: String) : Event()
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.events
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventUpdateOverviewProfile(val from: String) : Event()
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.events
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventUpdateOverviewTemporaryBasal(val from: String) : Event()
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.events
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventUpdateOverviewTemporaryTarget(val from: String) : Event()
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.events
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventUpdateOverviewTime(val from: String) : Event()
|
|
|
@ -9,17 +9,20 @@ import androidx.core.app.RemoteInput
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.events.*
|
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||||
|
import info.nightscout.androidaps.events.EventInitializationChanged
|
||||||
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
|
import info.nightscout.androidaps.events.EventRefreshOverview
|
||||||
import info.nightscout.androidaps.extensions.toStringShort
|
import info.nightscout.androidaps.extensions.toStringShort
|
||||||
import info.nightscout.androidaps.extensions.valueToUnitsString
|
import info.nightscout.androidaps.extensions.valueToUnitsString
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -72,26 +75,10 @@ class PersistentNotificationPlugin @Inject constructor(
|
||||||
.toObservable(EventRefreshOverview::class.java)
|
.toObservable(EventRefreshOverview::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventExtendedBolusChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTempBasalChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventTreatmentChange::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventInitializationChanged::class.java)
|
.toObservable(EventInitializationChanged::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ triggerNotificationUpdate() }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.SystemClock
|
|
||||||
import androidx.collection.LongSparseArray
|
import androidx.collection.LongSparseArray
|
||||||
import androidx.work.ExistingWorkPolicy
|
|
||||||
import androidx.work.OneTimeWorkRequest
|
|
||||||
import androidx.work.WorkInfo
|
|
||||||
import androidx.work.WorkManager
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
@ -24,21 +18,19 @@ import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||||
import info.nightscout.androidaps.extensions.iobCalc
|
import info.nightscout.androidaps.extensions.iobCalc
|
||||||
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.shared.logging.LTag
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
|
||||||
import info.nightscout.androidaps.receivers.DataWorker
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
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.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.androidaps.workflow.CalculationWorkflow
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
@ -63,14 +55,11 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val activePlugin: ActivePlugin,
|
private val activePlugin: ActivePlugin,
|
||||||
private val sensitivityOref1Plugin: SensitivityOref1Plugin,
|
|
||||||
private val sensitivityAAPSPlugin: SensitivityAAPSPlugin,
|
|
||||||
private val sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin,
|
|
||||||
private val fabricPrivacy: FabricPrivacy,
|
private val fabricPrivacy: FabricPrivacy,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
private val repository: AppRepository,
|
private val repository: AppRepository,
|
||||||
private val context: Context,
|
val overviewData: OverviewData,
|
||||||
private val dataWorker: DataWorker
|
private val calculationWorkflow: CalculationWorkflow
|
||||||
) : PluginBase(
|
) : PluginBase(
|
||||||
PluginDescription()
|
PluginDescription()
|
||||||
.mainType(PluginType.GENERAL)
|
.mainType(PluginType.GENERAL)
|
||||||
|
@ -91,8 +80,6 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
private val dataLock = Any()
|
private val dataLock = Any()
|
||||||
private var thread: Thread? = null
|
private var thread: Thread? = null
|
||||||
|
|
||||||
private val jobGroupName = "calculation"
|
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
// EventConfigBuilderChange
|
// EventConfigBuilderChange
|
||||||
|
@ -126,14 +113,6 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
resetDataAndRunCalculation("onEventPreferenceChange", event)
|
resetDataAndRunCalculation("onEventPreferenceChange", event)
|
||||||
}
|
}
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
// EventAppInitialized
|
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventAppInitialized::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe(
|
|
||||||
{ event -> runCalculation("onEventAppInitialized", System.currentTimeMillis(), bgDataReload = true, limitDataToOldestAvailable = true, cause = event) },
|
|
||||||
fabricPrivacy::logException
|
|
||||||
)
|
|
||||||
// EventNewHistoryData
|
// EventNewHistoryData
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNewHistoryData::class.java)
|
.toObservable(EventNewHistoryData::class.java)
|
||||||
|
@ -147,10 +126,10 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetDataAndRunCalculation(reason: String, event: Event?) {
|
private fun resetDataAndRunCalculation(reason: String, event: Event?) {
|
||||||
stopCalculation(reason)
|
calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,reason)
|
||||||
clearCache()
|
clearCache()
|
||||||
ads.reset()
|
ads.reset()
|
||||||
runCalculation(reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event)
|
calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event, runLoop = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearCache() {
|
override fun clearCache() {
|
||||||
|
@ -310,11 +289,7 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
override fun getMealDataWithWaitingForCalculationFinish(): MealData {
|
override fun getMealDataWithWaitingForCalculationFinish(): MealData {
|
||||||
val result = MealData()
|
val result = MealData()
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
val maxAbsorptionHours: Double = if (sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()) {
|
val maxAbsorptionHours: Double = activePlugin.activeSensitivity.maxAbsorptionHours()
|
||||||
sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
|
||||||
} else {
|
|
||||||
sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
|
||||||
}
|
|
||||||
val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong()
|
val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong()
|
||||||
repository.getCarbsDataFromTimeToTimeExpanded(absorptionTimeAgo + 1, now, true)
|
repository.getCarbsDataFromTimeToTimeExpanded(absorptionTimeAgo + 1, now, true)
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
|
@ -374,34 +349,6 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopCalculation(from: String) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Stopping calculation thread: $from")
|
|
||||||
WorkManager.getInstance(context).cancelUniqueWork(jobGroupName)
|
|
||||||
val workStatus = WorkManager.getInstance(context).getWorkInfosForUniqueWork(jobGroupName).get()
|
|
||||||
while (workStatus.size >= 1 && workStatus[0].state == WorkInfo.State.RUNNING)
|
|
||||||
SystemClock.sleep(100)
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Calculation thread stopped: $from")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun runCalculation(from: String, end: Long, bgDataReload: Boolean, limitDataToOldestAvailable: Boolean, cause: Event?) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Starting calculation worker: $from to ${dateUtil.dateAndTimeAndSecondsString(end)}")
|
|
||||||
|
|
||||||
val iobCalculation =
|
|
||||||
if (sensitivityOref1Plugin.isEnabled())
|
|
||||||
OneTimeWorkRequest.Builder(IobCobOref1Worker::class.java)
|
|
||||||
.setInputData(
|
|
||||||
dataWorker.storeInputData(IobCobOref1Worker.IobCobOref1WorkerData(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause))
|
|
||||||
).build()
|
|
||||||
else
|
|
||||||
OneTimeWorkRequest.Builder(IobCobOref1Worker::class.java)
|
|
||||||
.setInputData(
|
|
||||||
dataWorker.storeInputData(IobCobOrefWorker.IobCobOrefWorkerData(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause))
|
|
||||||
).build()
|
|
||||||
|
|
||||||
WorkManager.getInstance(context)
|
|
||||||
.enqueueUniqueWork(jobGroupName, ExistingWorkPolicy.REPLACE, iobCalculation)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limit rate of EventNewHistoryData
|
// Limit rate of EventNewHistoryData
|
||||||
private val historyWorker = Executors.newSingleThreadScheduledExecutor()
|
private val historyWorker = Executors.newSingleThreadScheduledExecutor()
|
||||||
private var scheduledHistoryPost: ScheduledFuture<*>? = null
|
private var scheduledHistoryPost: ScheduledFuture<*>? = null
|
||||||
|
@ -443,7 +390,7 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
// When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated
|
// When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated
|
||||||
private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) {
|
private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) {
|
||||||
//log.debug("Locking onNewHistoryData");
|
//log.debug("Locking onNewHistoryData");
|
||||||
stopCalculation("onEventNewHistoryData")
|
calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,"onEventNewHistoryData")
|
||||||
synchronized(dataLock) {
|
synchronized(dataLock) {
|
||||||
|
|
||||||
// clear up 5 min back for proper COB calculation
|
// clear up 5 min back for proper COB calculation
|
||||||
|
@ -467,7 +414,7 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
ads.newHistoryData(time, aapsLogger, dateUtil)
|
ads.newHistoryData(time, aapsLogger, dateUtil)
|
||||||
}
|
}
|
||||||
runCalculation(event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event)
|
calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event, runLoop = true)
|
||||||
//log.debug("Releasing onNewHistoryData");
|
//log.debug("Releasing onNewHistoryData");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import info.nightscout.androidaps.utils.Profiler
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.workflow.CalculationWorkflow
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
|
@ -62,6 +63,7 @@ class IobCobOref1Worker(
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Inject lateinit var repository: AppRepository
|
@Inject lateinit var repository: AppRepository
|
||||||
@Inject lateinit var dataWorker: DataWorker
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var calculationWorkflow: CalculationWorkflow
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -69,10 +71,9 @@ class IobCobOref1Worker(
|
||||||
|
|
||||||
class IobCobOref1WorkerData(
|
class IobCobOref1WorkerData(
|
||||||
val injector: HasAndroidInjector,
|
val injector: HasAndroidInjector,
|
||||||
val iobCobCalculatorPlugin: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
val iobCobCalculator: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
||||||
val from: String,
|
val from: String,
|
||||||
val end: Long,
|
val end: Long,
|
||||||
val bgDataReload: Boolean,
|
|
||||||
val limitDataToOldestAvailable: Boolean,
|
val limitDataToOldestAvailable: Boolean,
|
||||||
val cause: Event?
|
val cause: Event?
|
||||||
)
|
)
|
||||||
|
@ -90,13 +91,9 @@ class IobCobOref1Worker(
|
||||||
return Result.failure(workDataOf("Error" to "app still initializing"))
|
return Result.failure(workDataOf("Error" to "app still initializing"))
|
||||||
}
|
}
|
||||||
//log.debug("Locking calculateSensitivityData");
|
//log.debug("Locking calculateSensitivityData");
|
||||||
val oldestTimeWithData = data.iobCobCalculatorPlugin.calculateDetectionStart(data.end, data.limitDataToOldestAvailable)
|
val oldestTimeWithData = data.iobCobCalculator.calculateDetectionStart(data.end, data.limitDataToOldestAvailable)
|
||||||
if (data.bgDataReload) {
|
|
||||||
data.iobCobCalculatorPlugin.ads.loadBgData(data.end, repository, aapsLogger, dateUtil, rxBus)
|
|
||||||
data.iobCobCalculatorPlugin.clearCache()
|
|
||||||
}
|
|
||||||
// work on local copy and set back when finished
|
// work on local copy and set back when finished
|
||||||
val ads = data.iobCobCalculatorPlugin.ads.clone()
|
val ads = data.iobCobCalculator.ads.clone()
|
||||||
val bucketedData = ads.bucketedData
|
val bucketedData = ads.bucketedData
|
||||||
val autosensDataTable = ads.autosensDataTable
|
val autosensDataTable = ads.autosensDataTable
|
||||||
if (bucketedData == null || bucketedData.size < 3) {
|
if (bucketedData == null || bucketedData.size < 3) {
|
||||||
|
@ -108,8 +105,7 @@ class IobCobOref1Worker(
|
||||||
var previous = autosensDataTable[prevDataTime]
|
var previous = autosensDataTable[prevDataTime]
|
||||||
// start from oldest to be able sub cob
|
// start from oldest to be able sub cob
|
||||||
for (i in bucketedData.size - 4 downTo 0) {
|
for (i in bucketedData.size - 4 downTo 0) {
|
||||||
val progress = i.toString() + if (buildHelper.isDev()) " (${data.from})" else ""
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.IOB_COB_OREF, 100 - (100.0 * i / bucketedData.size).toInt(), data.cause))
|
||||||
rxBus.send(EventIobCalculationProgress(100 - (100.0 * i / bucketedData.size).toInt(), data.cause))
|
|
||||||
if (isStopped) {
|
if (isStopped) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): ${data.from}")
|
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): ${data.from}")
|
||||||
return Result.failure(workDataOf("Error" to "Aborting calculation thread (trigger): ${data.from}"))
|
return Result.failure(workDataOf("Error" to "Aborting calculation thread (trigger): ${data.from}"))
|
||||||
|
@ -145,7 +141,7 @@ class IobCobOref1Worker(
|
||||||
autosensData.bg = bg
|
autosensData.bg = bg
|
||||||
delta = bg - bucketedData[i + 1].value
|
delta = bg - bucketedData[i + 1].value
|
||||||
avgDelta = (bg - bucketedData[i + 3].value) / 3
|
avgDelta = (bg - bucketedData[i + 3].value) / 3
|
||||||
val iob = data.iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime, profile)
|
val iob = data.iobCobCalculator.calculateFromTreatmentsAndTemps(bgTime, profile)
|
||||||
val bgi = -iob.activity * sens * 5
|
val bgi = -iob.activity * sens * 5
|
||||||
val deviation = delta - bgi
|
val deviation = delta - bgi
|
||||||
val avgDeviation = ((avgDelta - bgi) * 1000).roundToLong() / 1000.0
|
val avgDeviation = ((avgDelta - bgi) * 1000).roundToLong() / 1000.0
|
||||||
|
@ -332,13 +328,13 @@ class IobCobOref1Worker(
|
||||||
autosensData.autosensResult = sensitivity
|
autosensData.autosensResult = sensitivity
|
||||||
aapsLogger.debug(LTag.AUTOSENS, autosensData.toString())
|
aapsLogger.debug(LTag.AUTOSENS, autosensData.toString())
|
||||||
}
|
}
|
||||||
data.iobCobCalculatorPlugin.ads = ads
|
data.iobCobCalculator.ads = ads
|
||||||
Thread {
|
Thread {
|
||||||
SystemClock.sleep(1000)
|
SystemClock.sleep(1000)
|
||||||
rxBus.send(EventAutosensCalculationFinished(data.cause))
|
rxBus.send(EventAutosensCalculationFinished(data.cause))
|
||||||
}.start()
|
}.start()
|
||||||
} finally {
|
} finally {
|
||||||
rxBus.send(EventIobCalculationProgress(100, data.cause))
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.IOB_COB_OREF, 100, data.cause))
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: ${data.from}")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: ${data.from}")
|
||||||
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
|
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import info.nightscout.androidaps.utils.Profiler
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.workflow.CalculationWorkflow
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
|
@ -69,7 +70,6 @@ class IobCobOrefWorker @Inject internal constructor(
|
||||||
val iobCobCalculatorPlugin: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
val iobCobCalculatorPlugin: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
||||||
val from: String,
|
val from: String,
|
||||||
val end: Long,
|
val end: Long,
|
||||||
val bgDataReload: Boolean,
|
|
||||||
val limitDataToOldestAvailable: Boolean,
|
val limitDataToOldestAvailable: Boolean,
|
||||||
val cause: Event?
|
val cause: Event?
|
||||||
)
|
)
|
||||||
|
@ -87,10 +87,6 @@ class IobCobOrefWorker @Inject internal constructor(
|
||||||
}
|
}
|
||||||
//log.debug("Locking calculateSensitivityData");
|
//log.debug("Locking calculateSensitivityData");
|
||||||
val oldestTimeWithData = data.iobCobCalculatorPlugin.calculateDetectionStart(data.end, data.limitDataToOldestAvailable)
|
val oldestTimeWithData = data.iobCobCalculatorPlugin.calculateDetectionStart(data.end, data.limitDataToOldestAvailable)
|
||||||
if (data.bgDataReload) {
|
|
||||||
data.iobCobCalculatorPlugin.ads.loadBgData(data.end, repository, aapsLogger, dateUtil, rxBus)
|
|
||||||
data.iobCobCalculatorPlugin.clearCache()
|
|
||||||
}
|
|
||||||
// work on local copy and set back when finished
|
// work on local copy and set back when finished
|
||||||
val ads = data.iobCobCalculatorPlugin.ads.clone()
|
val ads = data.iobCobCalculatorPlugin.ads.clone()
|
||||||
val bucketedData = ads.bucketedData
|
val bucketedData = ads.bucketedData
|
||||||
|
@ -104,8 +100,7 @@ class IobCobOrefWorker @Inject internal constructor(
|
||||||
var previous = autosensDataTable[prevDataTime]
|
var previous = autosensDataTable[prevDataTime]
|
||||||
// start from oldest to be able sub cob
|
// start from oldest to be able sub cob
|
||||||
for (i in bucketedData.size - 4 downTo 0) {
|
for (i in bucketedData.size - 4 downTo 0) {
|
||||||
val progress = i.toString() + if (buildHelper.isDev()) " (${data.from})" else ""
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.IOB_COB_OREF, 100 - (100.0 * i / bucketedData.size).toInt(), data.cause))
|
||||||
rxBus.send(EventIobCalculationProgress(100 - (100.0 * i / bucketedData.size).toInt(), data.cause))
|
|
||||||
if (isStopped) {
|
if (isStopped) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): ${data.from}")
|
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): ${data.from}")
|
||||||
return Result.failure(workDataOf("Error" to "Aborting calculation thread (trigger): ${data.from}"))
|
return Result.failure(workDataOf("Error" to "Aborting calculation thread (trigger): ${data.from}"))
|
||||||
|
@ -282,7 +277,7 @@ class IobCobOrefWorker @Inject internal constructor(
|
||||||
rxBus.send(EventAutosensCalculationFinished(data.cause))
|
rxBus.send(EventAutosensCalculationFinished(data.cause))
|
||||||
}.start()
|
}.start()
|
||||||
} finally {
|
} finally {
|
||||||
rxBus.send(EventIobCalculationProgress(100, data.cause))
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.IOB_COB_OREF, 100, data.cause))
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: ${data.from}")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: ${data.from}")
|
||||||
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
|
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
|
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
import info.nightscout.androidaps.events.Event
|
||||||
|
import info.nightscout.androidaps.workflow.CalculationWorkflow
|
||||||
|
|
||||||
class EventIobCalculationProgress(val progressPct: Int, val cause: Event?) : Event()
|
class EventIobCalculationProgress(val pass: CalculationWorkflow.ProgressData, val progressPct: Int, val cause: Event?) : Event()
|
|
@ -137,6 +137,8 @@ class SensitivityAAPSPlugin @Inject constructor(
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun maxAbsorptionHours(): Double = sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||||
|
|
||||||
override val id: SensitivityType
|
override val id: SensitivityType
|
||||||
get() = SensitivityType.SENSITIVITY_AAPS
|
get() = SensitivityType.SENSITIVITY_AAPS
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,8 @@ class SensitivityOref1Plugin @Inject constructor(
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun maxAbsorptionHours(): Double = sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||||
|
|
||||||
override fun configuration(): JSONObject {
|
override fun configuration(): JSONObject {
|
||||||
val c = JSONObject()
|
val c = JSONObject()
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -157,6 +157,8 @@ class SensitivityWeightedAveragePlugin @Inject constructor(
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun maxAbsorptionHours(): Double = sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||||
|
|
||||||
override val id: SensitivityType
|
override val id: SensitivityType
|
||||||
get() = SensitivityType.SENSITIVITY_WEIGHTED
|
get() = SensitivityType.SENSITIVITY_WEIGHTED
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,270 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.SystemClock
|
||||||
|
import androidx.work.*
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.events.Event
|
||||||
|
import info.nightscout.androidaps.events.EventAppInitialized
|
||||||
|
import info.nightscout.androidaps.events.EventOfflineChange
|
||||||
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
|
import info.nightscout.androidaps.events.EventTherapyEventChange
|
||||||
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Worker
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOrefWorker
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||||
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class CalculationWorkflow @Inject constructor(
|
||||||
|
aapsSchedulers: AapsSchedulers,
|
||||||
|
rh: ResourceHelper,
|
||||||
|
rxBus: RxBus,
|
||||||
|
private val context: Context,
|
||||||
|
private val injector: HasAndroidInjector,
|
||||||
|
private val aapsLogger: AAPSLogger,
|
||||||
|
private val fabricPrivacy: FabricPrivacy,
|
||||||
|
private val dateUtil: DateUtil,
|
||||||
|
private val sensitivityOref1Plugin: SensitivityOref1Plugin,
|
||||||
|
private val dataWorker: DataWorker,
|
||||||
|
private val activePlugin: ActivePlugin
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
const val MAIN_CALCULATION = "calculation"
|
||||||
|
const val HISTORY_CALCULATION = "history_calculation"
|
||||||
|
const val JOB = "job"
|
||||||
|
}
|
||||||
|
|
||||||
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
|
private val iobCobCalculator: IobCobCalculator
|
||||||
|
get() = activePlugin.activeIobCobCalculator // cross-dependency CalculationWorkflow x IobCobCalculator
|
||||||
|
private val overviewData: OverviewData
|
||||||
|
get() = (iobCobCalculator as IobCobCalculatorPlugin).overviewData
|
||||||
|
|
||||||
|
enum class ProgressData(val pass: Int, val percentOfTotal: Int) {
|
||||||
|
PREPARE_BASAL_DATA(0, 5),
|
||||||
|
PREPARE_TEMPORARY_TARGET_DATA(1, 5),
|
||||||
|
PREPARE_TREATMENTS_DATA(2, 5),
|
||||||
|
IOB_COB_OREF(3, 75),
|
||||||
|
PREPARE_IOB_AUTOSENS_DATA(4, 10);
|
||||||
|
|
||||||
|
fun finalPercent(progress: Int): Int {
|
||||||
|
var total = 0
|
||||||
|
for (i in values()) if (i.pass < pass) total += i.percentOfTotal
|
||||||
|
total += (percentOfTotal.toDouble() * progress / 100.0).toInt()
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
// Verify definition
|
||||||
|
var sumPercent = 0
|
||||||
|
for (pass in ProgressData.values()) sumPercent += pass.percentOfTotal
|
||||||
|
require(sumPercent == 100)
|
||||||
|
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventTherapyEventChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.io)
|
||||||
|
.subscribe({ runOnEventTherapyEventChange() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventOfflineChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.io)
|
||||||
|
.subscribe({ runOnEventTherapyEventChange() }, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventPreferenceChange::class.java)
|
||||||
|
.observeOn(aapsSchedulers.io)
|
||||||
|
.subscribe({ event ->
|
||||||
|
if (event.isChanged(rh, R.string.key_units)) {
|
||||||
|
overviewData.reset()
|
||||||
|
rxBus.send(EventNewHistoryData(0, false))
|
||||||
|
}
|
||||||
|
if (event.isChanged(rh, R.string.key_rangetodisplay)) {
|
||||||
|
overviewData.initRange()
|
||||||
|
runOnScaleChanged()
|
||||||
|
rxBus.send(EventNewHistoryData(0, false))
|
||||||
|
}
|
||||||
|
}, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventAppInitialized::class.java)
|
||||||
|
.observeOn(aapsSchedulers.io)
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
runCalculation(
|
||||||
|
MAIN_CALCULATION,
|
||||||
|
iobCobCalculator,
|
||||||
|
overviewData,
|
||||||
|
"onEventAppInitialized",
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
bgDataReload = true,
|
||||||
|
limitDataToOldestAvailable = true,
|
||||||
|
cause = it,
|
||||||
|
runLoop = true
|
||||||
|
)
|
||||||
|
},
|
||||||
|
fabricPrivacy::logException
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopCalculation(job: String, from: String) {
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Stopping calculation thread: $from")
|
||||||
|
WorkManager.getInstance(context).cancelUniqueWork(job)
|
||||||
|
val workStatus = WorkManager.getInstance(context).getWorkInfosForUniqueWork(job).get()
|
||||||
|
while (workStatus.size >= 1 && workStatus[0].state == WorkInfo.State.RUNNING)
|
||||||
|
SystemClock.sleep(100)
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Calculation thread stopped: $from")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runCalculation(
|
||||||
|
job: String,
|
||||||
|
iobCobCalculator: IobCobCalculator,
|
||||||
|
overviewData: OverviewData,
|
||||||
|
from: String,
|
||||||
|
end: Long,
|
||||||
|
bgDataReload: Boolean,
|
||||||
|
limitDataToOldestAvailable: Boolean,
|
||||||
|
cause: Event?,
|
||||||
|
runLoop: Boolean
|
||||||
|
) {
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Starting calculation worker: $from to ${dateUtil.dateAndTimeAndSecondsString(end)}")
|
||||||
|
|
||||||
|
WorkManager.getInstance(context)
|
||||||
|
.beginUniqueWork(
|
||||||
|
job, ExistingWorkPolicy.REPLACE,
|
||||||
|
if (bgDataReload) OneTimeWorkRequest.Builder(LoadBgDataWorker::class.java).setInputData(dataWorker.storeInputData(LoadBgDataWorker.LoadBgData(iobCobCalculator, end))).build()
|
||||||
|
else OneTimeWorkRequest.Builder(DummyWorker::class.java).build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(PrepareBucketedDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareBucketedDataWorker.PrepareBucketedData(iobCobCalculator, overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(PrepareBgDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareBgDataWorker.PrepareBgData(iobCobCalculator, overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
|
||||||
|
.setInputData(Data.Builder().putString(JOB, job).build())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(PrepareTreatmentsDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareTreatmentsDataWorker.PrepareTreatmentsData(overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(PrepareBasalDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareBasalDataWorker.PrepareBasalData(iobCobCalculator, overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(PrepareTemporaryTargetDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareTemporaryTargetDataWorker.PrepareTemporaryTargetData(overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
|
||||||
|
.setInputData(Data.Builder().putString(JOB, job).build())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
if (sensitivityOref1Plugin.isEnabled())
|
||||||
|
OneTimeWorkRequest.Builder(IobCobOref1Worker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(IobCobOref1Worker.IobCobOref1WorkerData(injector, iobCobCalculator, from, end, limitDataToOldestAvailable, cause)))
|
||||||
|
.build()
|
||||||
|
else
|
||||||
|
OneTimeWorkRequest.Builder(IobCobOrefWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(IobCobOrefWorker.IobCobOrefWorkerData(injector, iobCobCalculator, from, end, limitDataToOldestAvailable, cause)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(OneTimeWorkRequest.Builder(UpdateIobCobSensWorker::class.java).build())
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(PrepareIobAutosensGraphDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareIobAutosensGraphDataWorker.PrepareIobAutosensData(iobCobCalculator, overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
|
||||||
|
.setInputData(Data.Builder().putString(JOB, job).build())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
runLoop,
|
||||||
|
OneTimeWorkRequest.Builder(InvokeLoopWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(InvokeLoopWorker.InvokeLoopData(cause)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
runLoop,
|
||||||
|
OneTimeWorkRequest.Builder(PreparePredictionsWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PreparePredictionsWorker.PreparePredictionsData(overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
runLoop, OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
|
||||||
|
.setInputData(Data.Builder().putString(JOB, job).build())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun WorkContinuation.then(shouldAdd: Boolean, work: OneTimeWorkRequest): WorkContinuation =
|
||||||
|
if (shouldAdd) then(work) else this
|
||||||
|
|
||||||
|
private fun runOnEventTherapyEventChange() {
|
||||||
|
WorkManager.getInstance(context)
|
||||||
|
.beginUniqueWork(
|
||||||
|
MAIN_CALCULATION, ExistingWorkPolicy.APPEND,
|
||||||
|
OneTimeWorkRequest.Builder(PrepareTreatmentsDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareTreatmentsDataWorker.PrepareTreatmentsData(overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.enqueue()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runOnScaleChanged() {
|
||||||
|
WorkManager.getInstance(context)
|
||||||
|
.beginUniqueWork(
|
||||||
|
MAIN_CALCULATION, ExistingWorkPolicy.APPEND,
|
||||||
|
OneTimeWorkRequest.Builder(PrepareBucketedDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareBucketedDataWorker.PrepareBucketedData(iobCobCalculator, overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(PrepareBgDataWorker::class.java)
|
||||||
|
.setInputData(dataWorker.storeInputData(PrepareBgDataWorker.PrepareBgData(iobCobCalculator, overviewData)))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.enqueue()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
|
||||||
|
class DummyWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
override fun doWork(): Result = Result.success()
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.events.Event
|
||||||
|
import info.nightscout.androidaps.events.EventNewBG
|
||||||
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.interfaces.Loop
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class InvokeLoopWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||||
|
@Inject lateinit var loop: Loop
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class InvokeLoopData(
|
||||||
|
val cause: Event?
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is triggered once autosens calculation has completed, so the LoopPlugin
|
||||||
|
has current data to work with. However, autosens calculation can be triggered by multiple
|
||||||
|
sources and currently only a new BG should trigger a loop run. Hence we return early if
|
||||||
|
the event causing the calculation is not EventNewBg.
|
||||||
|
<p>
|
||||||
|
*/
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as InvokeLoopData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
if (data.cause !is EventNewBG) return Result.success(workDataOf("Result" to "no calculation needed"))
|
||||||
|
val glucoseValue = iobCobCalculator.ads.actualBg() ?: return Result.success(workDataOf("Result" to "bg outdated"))
|
||||||
|
if (glucoseValue.timestamp <= loop.lastBgTriggeredRun) return Result.success(workDataOf("Result" to "already looped with that value"))
|
||||||
|
loop.lastBgTriggeredRun = glucoseValue.timestamp
|
||||||
|
loop.invoke("Calculation for $glucoseValue", true)
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LoadBgDataWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoadBgData(
|
||||||
|
val iobCobCalculator: IobCobCalculator,
|
||||||
|
val end: Long
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as LoadBgData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
data.iobCobCalculator.ads.loadBgData(data.end, repository, aapsLogger, dateUtil, rxBus)
|
||||||
|
data.iobCobCalculator.clearCache()
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.DashPathEffect
|
||||||
|
import android.graphics.Paint
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import java.util.ArrayList
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class PrepareBasalDataWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrepareBasalData(
|
||||||
|
val iobCobCalculator: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
||||||
|
val overviewData: OverviewData
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as PrepareBasalData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_BASAL_DATA, 0, null))
|
||||||
|
data.overviewData.maxBasalValueFound = 0.0
|
||||||
|
val baseBasalArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val tempBasalArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val basalLineArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val absoluteBasalLineArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
var lastLineBasal = 0.0
|
||||||
|
var lastAbsoluteLineBasal = -1.0
|
||||||
|
var lastBaseBasal = 0.0
|
||||||
|
var lastTempBasal = 0.0
|
||||||
|
var time = data.overviewData.fromTime
|
||||||
|
while (time < data.overviewData.toTime) {
|
||||||
|
val progress = (time - data.overviewData.fromTime).toDouble() / (data.overviewData.toTime - data.overviewData.fromTime) * 100.0
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_BASAL_DATA, progress.toInt(), null))
|
||||||
|
val profile = profileFunction.getProfile(time)
|
||||||
|
if (profile == null) {
|
||||||
|
time += 60 * 1000L
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val basalData = data.iobCobCalculator.getBasalData(profile, time)
|
||||||
|
val baseBasalValue = basalData.basal
|
||||||
|
var absoluteLineValue = baseBasalValue
|
||||||
|
var tempBasalValue = 0.0
|
||||||
|
var basal = 0.0
|
||||||
|
if (basalData.isTempBasalRunning) {
|
||||||
|
tempBasalValue = basalData.tempBasalAbsolute
|
||||||
|
absoluteLineValue = tempBasalValue
|
||||||
|
if (tempBasalValue != lastTempBasal) {
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, lastTempBasal, data.overviewData.basalScale))
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, tempBasalValue.also { basal = it }, data.overviewData.basalScale))
|
||||||
|
}
|
||||||
|
if (lastBaseBasal != 0.0) {
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, data.overviewData.basalScale))
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, 0.0, data.overviewData.basalScale))
|
||||||
|
lastBaseBasal = 0.0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (baseBasalValue != lastBaseBasal) {
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, data.overviewData.basalScale))
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, baseBasalValue.also { basal = it }, data.overviewData.basalScale))
|
||||||
|
lastBaseBasal = baseBasalValue
|
||||||
|
}
|
||||||
|
if (lastTempBasal != 0.0) {
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, lastTempBasal, data.overviewData.basalScale))
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, 0.0, data.overviewData.basalScale))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (baseBasalValue != lastLineBasal) {
|
||||||
|
basalLineArray.add(ScaledDataPoint(time, lastLineBasal, data.overviewData.basalScale))
|
||||||
|
basalLineArray.add(ScaledDataPoint(time, baseBasalValue, data.overviewData.basalScale))
|
||||||
|
}
|
||||||
|
if (absoluteLineValue != lastAbsoluteLineBasal) {
|
||||||
|
absoluteBasalLineArray.add(ScaledDataPoint(time, lastAbsoluteLineBasal, data.overviewData.basalScale))
|
||||||
|
absoluteBasalLineArray.add(ScaledDataPoint(time, basal, data.overviewData.basalScale))
|
||||||
|
}
|
||||||
|
lastAbsoluteLineBasal = absoluteLineValue
|
||||||
|
lastLineBasal = baseBasalValue
|
||||||
|
lastTempBasal = tempBasalValue
|
||||||
|
data.overviewData.maxBasalValueFound = max(data.overviewData.maxBasalValueFound, max(tempBasalValue, baseBasalValue))
|
||||||
|
time += 60 * 1000L
|
||||||
|
}
|
||||||
|
|
||||||
|
// final points
|
||||||
|
basalLineArray.add(ScaledDataPoint(data.overviewData.toTime, lastLineBasal, data.overviewData.basalScale))
|
||||||
|
baseBasalArray.add(ScaledDataPoint(data.overviewData.toTime, lastBaseBasal, data.overviewData.basalScale))
|
||||||
|
tempBasalArray.add(ScaledDataPoint(data.overviewData.toTime, lastTempBasal, data.overviewData.basalScale))
|
||||||
|
absoluteBasalLineArray.add(ScaledDataPoint(data.overviewData.toTime, lastAbsoluteLineBasal, data.overviewData.basalScale))
|
||||||
|
|
||||||
|
// create series
|
||||||
|
data.overviewData.baseBasalGraphSeries = LineGraphSeries(Array(baseBasalArray.size) { i -> baseBasalArray[i] }).also {
|
||||||
|
it.isDrawBackground = true
|
||||||
|
it.backgroundColor = rh.gc(R.color.basebasal)
|
||||||
|
it.thickness = 0
|
||||||
|
}
|
||||||
|
data.overviewData.tempBasalGraphSeries = LineGraphSeries(Array(tempBasalArray.size) { i -> tempBasalArray[i] }).also {
|
||||||
|
it.isDrawBackground = true
|
||||||
|
it.backgroundColor = rh.gc(R.color.tempbasal)
|
||||||
|
it.thickness = 0
|
||||||
|
}
|
||||||
|
data.overviewData.basalLineGraphSeries = LineGraphSeries(Array(basalLineArray.size) { i -> basalLineArray[i] }).also {
|
||||||
|
it.setCustomPaint(Paint().also { paint ->
|
||||||
|
paint.style = Paint.Style.STROKE
|
||||||
|
paint.strokeWidth = rh.getDisplayMetrics().scaledDensity * 2
|
||||||
|
paint.pathEffect = DashPathEffect(floatArrayOf(2f, 4f), 0f)
|
||||||
|
paint.color = rh.gc(R.color.basal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
data.overviewData.absoluteBasalGraphSeries = LineGraphSeries(Array(absoluteBasalLineArray.size) { i -> absoluteBasalLineArray[i] }).also {
|
||||||
|
it.setCustomPaint(Paint().also { absolutePaint ->
|
||||||
|
absolutePaint.style = Paint.Style.STROKE
|
||||||
|
absolutePaint.strokeWidth = rh.getDisplayMetrics().scaledDensity * 2
|
||||||
|
absolutePaint.color = rh.gc(R.color.basal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_BASAL_DATA, 100, null))
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import java.util.ArrayList
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class PrepareBgDataWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrepareBgData(
|
||||||
|
val iobCobCalculator: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
||||||
|
val overviewData: OverviewData
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as PrepareBgData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
data.overviewData.maxBgValue = Double.MIN_VALUE
|
||||||
|
data.overviewData.bgReadingsArray = repository.compatGetBgReadingsDataFromTime(data.overviewData.fromTime, data.overviewData.toTime, false).blockingGet()
|
||||||
|
val bgListArray: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||||
|
for (bg in data.overviewData.bgReadingsArray) {
|
||||||
|
if (bg.timestamp < data.overviewData.fromTime || bg.timestamp > data.overviewData.toTime) continue
|
||||||
|
if (bg.value > data.overviewData.maxBgValue) data.overviewData.maxBgValue = bg.value
|
||||||
|
bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh))
|
||||||
|
}
|
||||||
|
bgListArray.sortWith { o1: DataPointWithLabelInterface, o2: DataPointWithLabelInterface -> o1.x.compareTo(o2.x) }
|
||||||
|
data.overviewData.bgReadingGraphSeries = PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] })
|
||||||
|
data.overviewData.maxBgValue = Profile.fromMgdlToUnits(data.overviewData.maxBgValue, profileFunction.getUnits())
|
||||||
|
if (defaultValueHelper.determineHighLine() > data.overviewData.maxBgValue) data.overviewData.maxBgValue = defaultValueHelper.determineHighLine()
|
||||||
|
data.overviewData.maxBgValue = addUpperChartMargin(data.overviewData.maxBgValue)
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addUpperChartMargin(maxBgValue: Double) =
|
||||||
|
if (profileFunction.getUnits() == GlucoseUnit.MGDL) Round.roundTo(maxBgValue, 40.0) + 80 else Round.roundTo(maxBgValue, 2.0) + 4
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.InMemoryGlucoseValueDataPoint
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class PrepareBucketedDataWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrepareBucketedData(
|
||||||
|
val iobCobCalculator: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
||||||
|
val overviewData: OverviewData
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as PrepareBucketedData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
val bucketedData = data.iobCobCalculator.ads.getBucketedDataTableCopy() ?: return Result.success()
|
||||||
|
if (bucketedData.isEmpty()) {
|
||||||
|
aapsLogger.debug("No bucketed data.")
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
val bucketedListArray: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||||
|
for (inMemoryGlucoseValue in bucketedData) {
|
||||||
|
if (inMemoryGlucoseValue.timestamp < data.overviewData.fromTime || inMemoryGlucoseValue.timestamp > data.overviewData.toTime) continue
|
||||||
|
bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, profileFunction, rh))
|
||||||
|
}
|
||||||
|
bucketedListArray.sortWith { o1: DataPointWithLabelInterface, o2: DataPointWithLabelInterface -> o1.x.compareTo(o2.x) }
|
||||||
|
data.overviewData.bucketedGraphSeries = PointsWithLabelGraphSeries(Array(bucketedListArray.size) { i -> bucketedListArray[i] })
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,284 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.DashPathEffect
|
||||||
|
import android.graphics.Paint
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import com.jjoe64.graphview.series.BarGraphSeries
|
||||||
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.FixedLineGraphSeries
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
|
import java.util.ArrayList
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
class PrepareIobAutosensGraphDataWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
@Inject lateinit var overviewMenus: OverviewMenus
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrepareIobAutosensData(
|
||||||
|
val iobCobCalculator: IobCobCalculator, // cannot be injected : HistoryBrowser uses different instance
|
||||||
|
val overviewData: OverviewData
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as PrepareIobAutosensData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_IOB_AUTOSENS_DATA, 0, null))
|
||||||
|
val iobArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val absIobArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
data.overviewData.maxIobValueFound = Double.MIN_VALUE
|
||||||
|
var lastIob = 0.0
|
||||||
|
var absLastIob = 0.0
|
||||||
|
var time = data.overviewData.fromTime
|
||||||
|
|
||||||
|
val minFailOverActiveList: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||||
|
val cobArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
data.overviewData.maxCobValueFound = Double.MIN_VALUE
|
||||||
|
var lastCob = 0
|
||||||
|
|
||||||
|
val actArrayHist: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val actArrayPrediction: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val now = dateUtil.now().toDouble()
|
||||||
|
data.overviewData.maxIAValue = 0.0
|
||||||
|
|
||||||
|
val bgiArrayHist: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val bgiArrayPrediction: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
data.overviewData.maxBGIValue = Double.MIN_VALUE
|
||||||
|
|
||||||
|
val devArray: MutableList<OverviewPlugin.DeviationDataPoint> = ArrayList()
|
||||||
|
data.overviewData.maxDevValueFound = Double.MIN_VALUE
|
||||||
|
|
||||||
|
val ratioArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
data.overviewData.maxRatioValueFound = 5.0 //even if sens data equals 0 for all the period, minimum scale is between 95% and 105%
|
||||||
|
data.overviewData.minRatioValueFound = -5.0
|
||||||
|
|
||||||
|
val dsMaxArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
val dsMinArray: MutableList<ScaledDataPoint> = ArrayList()
|
||||||
|
data.overviewData.maxFromMaxValueFound = Double.MIN_VALUE
|
||||||
|
data.overviewData.maxFromMinValueFound = Double.MIN_VALUE
|
||||||
|
|
||||||
|
val adsData = data.iobCobCalculator.ads.clone()
|
||||||
|
|
||||||
|
while (time <= data.overviewData.toTime) {
|
||||||
|
val progress = (time - data.overviewData.fromTime).toDouble() / (data.overviewData.toTime - data.overviewData.fromTime) * 100.0
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_IOB_AUTOSENS_DATA, progress.toInt(), null))
|
||||||
|
val profile = profileFunction.getProfile(time)
|
||||||
|
if (profile == null) {
|
||||||
|
time += 5 * 60 * 1000L
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// IOB
|
||||||
|
val iob = data.iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile)
|
||||||
|
val baseBasalIob = data.iobCobCalculator.calculateAbsoluteIobFromBaseBasals(time)
|
||||||
|
val absIob = IobTotal.combine(iob, baseBasalIob)
|
||||||
|
val autosensData = adsData.getAutosensDataAtTime(time)
|
||||||
|
if (abs(lastIob - iob.iob) > 0.02) {
|
||||||
|
if (abs(lastIob - iob.iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, data.overviewData.iobScale))
|
||||||
|
iobArray.add(ScaledDataPoint(time, iob.iob, data.overviewData.iobScale))
|
||||||
|
data.overviewData.maxIobValueFound = maxOf(data.overviewData.maxIobValueFound, abs(iob.iob))
|
||||||
|
lastIob = iob.iob
|
||||||
|
}
|
||||||
|
if (abs(absLastIob - absIob.iob) > 0.02) {
|
||||||
|
if (abs(absLastIob - absIob.iob) > 0.2) absIobArray.add(ScaledDataPoint(time, absLastIob, data.overviewData.iobScale))
|
||||||
|
absIobArray.add(ScaledDataPoint(time, absIob.iob, data.overviewData.iobScale))
|
||||||
|
data.overviewData.maxIobValueFound = maxOf(data.overviewData.maxIobValueFound, abs(absIob.iob))
|
||||||
|
absLastIob = absIob.iob
|
||||||
|
}
|
||||||
|
|
||||||
|
// COB
|
||||||
|
if (autosensData != null) {
|
||||||
|
val cob = autosensData.cob.toInt()
|
||||||
|
if (cob != lastCob) {
|
||||||
|
if (autosensData.carbsFromBolus > 0) cobArray.add(ScaledDataPoint(time, lastCob.toDouble(), data.overviewData.cobScale))
|
||||||
|
cobArray.add(ScaledDataPoint(time, cob.toDouble(), data.overviewData.cobScale))
|
||||||
|
data.overviewData.maxCobValueFound = max(data.overviewData.maxCobValueFound, cob.toDouble())
|
||||||
|
lastCob = cob
|
||||||
|
}
|
||||||
|
if (autosensData.failOverToMinAbsorptionRate) {
|
||||||
|
autosensData.scale = data.overviewData.cobScale
|
||||||
|
autosensData.chartTime = time
|
||||||
|
minFailOverActiveList.add(autosensData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ACTIVITY
|
||||||
|
if (time <= now) actArrayHist.add(ScaledDataPoint(time, iob.activity, data.overviewData.actScale))
|
||||||
|
else actArrayPrediction.add(ScaledDataPoint(time, iob.activity, data.overviewData.actScale))
|
||||||
|
data.overviewData.maxIAValue = max(data.overviewData.maxIAValue, abs(iob.activity))
|
||||||
|
|
||||||
|
// BGI
|
||||||
|
val devBgiScale = overviewMenus.isEnabledIn(OverviewMenus.CharType.DEV) == overviewMenus.isEnabledIn(OverviewMenus.CharType.BGI)
|
||||||
|
val deviation = if (devBgiScale) autosensData?.deviation ?: 0.0 else 0.0
|
||||||
|
val bgi: Double = iob.activity * profile.getIsfMgdl(time) * 5.0
|
||||||
|
if (time <= now) bgiArrayHist.add(ScaledDataPoint(time, bgi, data.overviewData.bgiScale))
|
||||||
|
else bgiArrayPrediction.add(ScaledDataPoint(time, bgi, data.overviewData.bgiScale))
|
||||||
|
data.overviewData.maxBGIValue = max(data.overviewData.maxBGIValue, max(abs(bgi), deviation))
|
||||||
|
|
||||||
|
// DEVIATIONS
|
||||||
|
if (autosensData != null) {
|
||||||
|
var color = rh.gc(R.color.deviationblack) // "="
|
||||||
|
if (autosensData.type == "" || autosensData.type == "non-meal") {
|
||||||
|
if (autosensData.pastSensitivity == "C") color = rh.gc(R.color.deviationgrey)
|
||||||
|
if (autosensData.pastSensitivity == "+") color = rh.gc(R.color.deviationgreen)
|
||||||
|
if (autosensData.pastSensitivity == "-") color = rh.gc(R.color.deviationred)
|
||||||
|
} else if (autosensData.type == "uam") {
|
||||||
|
color = rh.gc(R.color.uam)
|
||||||
|
} else if (autosensData.type == "csf") {
|
||||||
|
color = rh.gc(R.color.deviationgrey)
|
||||||
|
}
|
||||||
|
devArray.add(OverviewPlugin.DeviationDataPoint(time.toDouble(), autosensData.deviation, color, data.overviewData.devScale))
|
||||||
|
data.overviewData.maxDevValueFound = maxOf(data.overviewData.maxDevValueFound, abs(autosensData.deviation), abs(bgi))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RATIO
|
||||||
|
if (autosensData != null) {
|
||||||
|
ratioArray.add(ScaledDataPoint(time, 100.0 * (autosensData.autosensResult.ratio - 1), data.overviewData.ratioScale))
|
||||||
|
data.overviewData.maxRatioValueFound = max(data.overviewData.maxRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
|
||||||
|
data.overviewData.minRatioValueFound = min(data.overviewData.minRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEV SLOPE
|
||||||
|
if (autosensData != null) {
|
||||||
|
dsMaxArray.add(ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, data.overviewData.dsMaxScale))
|
||||||
|
dsMinArray.add(ScaledDataPoint(time, autosensData.slopeFromMinDeviation, data.overviewData.dsMinScale))
|
||||||
|
data.overviewData.maxFromMaxValueFound = max(data.overviewData.maxFromMaxValueFound, abs(autosensData.slopeFromMaxDeviation))
|
||||||
|
data.overviewData.maxFromMinValueFound = max(data.overviewData.maxFromMinValueFound, abs(autosensData.slopeFromMinDeviation))
|
||||||
|
}
|
||||||
|
|
||||||
|
time += 5 * 60 * 1000L
|
||||||
|
}
|
||||||
|
// IOB
|
||||||
|
data.overviewData.iobSeries = FixedLineGraphSeries(Array(iobArray.size) { i -> iobArray[i] }).also {
|
||||||
|
it.isDrawBackground = true
|
||||||
|
it.backgroundColor = -0x7f000001 and rh.gc(R.color.iob) //50%
|
||||||
|
it.color = rh.gc(R.color.iob)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
data.overviewData.absIobSeries = FixedLineGraphSeries(Array(absIobArray.size) { i -> absIobArray[i] }).also {
|
||||||
|
it.isDrawBackground = true
|
||||||
|
it.backgroundColor = -0x7f000001 and rh.gc(R.color.iob) //50%
|
||||||
|
it.color = rh.gc(R.color.iob)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overviewMenus.setting[0][OverviewMenus.CharType.PRE.ordinal]) {
|
||||||
|
val autosensData = adsData.getLastAutosensData("GraphData", aapsLogger, dateUtil)
|
||||||
|
val lastAutosensResult = autosensData?.autosensResult ?: AutosensResult()
|
||||||
|
val isTempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
|
||||||
|
val iobPrediction: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||||
|
val iobPredictionArray = data.iobCobCalculator.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
|
||||||
|
for (i in iobPredictionArray) {
|
||||||
|
iobPrediction.add(i.setColor(rh.gc(R.color.iobPredAS)))
|
||||||
|
data.overviewData.maxIobValueFound = max(data.overviewData.maxIobValueFound, abs(i.iob))
|
||||||
|
}
|
||||||
|
data.overviewData.iobPredictions1Series = PointsWithLabelGraphSeries(Array(iobPrediction.size) { i -> iobPrediction[i] })
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "IOB prediction for AS=" + DecimalFormatter.to2Decimal(lastAutosensResult.ratio) + ": " + data.iobCobCalculator.iobArrayToString(iobPredictionArray))
|
||||||
|
} else {
|
||||||
|
data.overviewData.iobPredictions1Series = PointsWithLabelGraphSeries()
|
||||||
|
}
|
||||||
|
|
||||||
|
// COB
|
||||||
|
data.overviewData.cobSeries = FixedLineGraphSeries(Array(cobArray.size) { i -> cobArray[i] }).also {
|
||||||
|
it.isDrawBackground = true
|
||||||
|
it.backgroundColor = -0x7f000001 and rh.gc(R.color.cob) //50%
|
||||||
|
it.color = rh.gc(R.color.cob)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
data.overviewData.cobMinFailOverSeries = PointsWithLabelGraphSeries(Array(minFailOverActiveList.size) { i -> minFailOverActiveList[i] })
|
||||||
|
|
||||||
|
// ACTIVITY
|
||||||
|
data.overviewData.activitySeries = FixedLineGraphSeries(Array(actArrayHist.size) { i -> actArrayHist[i] }).also {
|
||||||
|
it.isDrawBackground = false
|
||||||
|
it.color = rh.gc(R.color.activity)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
data.overviewData.activityPredictionSeries = FixedLineGraphSeries(Array(actArrayPrediction.size) { i -> actArrayPrediction[i] }).also {
|
||||||
|
it.setCustomPaint(Paint().also { paint ->
|
||||||
|
paint.style = Paint.Style.STROKE
|
||||||
|
paint.strokeWidth = 3f
|
||||||
|
paint.pathEffect = DashPathEffect(floatArrayOf(4f, 4f), 0f)
|
||||||
|
paint.color = rh.gc(R.color.activity)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// BGI
|
||||||
|
data.overviewData.minusBgiSeries = FixedLineGraphSeries(Array(bgiArrayHist.size) { i -> bgiArrayHist[i] }).also {
|
||||||
|
it.isDrawBackground = false
|
||||||
|
it.color = rh.gc(R.color.bgi)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
data.overviewData.minusBgiHistSeries = FixedLineGraphSeries(Array(bgiArrayPrediction.size) { i -> bgiArrayPrediction[i] }).also {
|
||||||
|
it.setCustomPaint(Paint().also { paint ->
|
||||||
|
paint.style = Paint.Style.STROKE
|
||||||
|
paint.strokeWidth = 3f
|
||||||
|
paint.pathEffect = DashPathEffect(floatArrayOf(4f, 4f), 0f)
|
||||||
|
paint.color = rh.gc(R.color.bgi)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEVIATIONS
|
||||||
|
data.overviewData.deviationsSeries = BarGraphSeries(Array(devArray.size) { i -> devArray[i] }).also {
|
||||||
|
it.setValueDependentColor { data: OverviewPlugin.DeviationDataPoint -> data.color }
|
||||||
|
}
|
||||||
|
|
||||||
|
// RATIO
|
||||||
|
data.overviewData.ratioSeries = LineGraphSeries(Array(ratioArray.size) { i -> ratioArray[i] }).also {
|
||||||
|
it.color = rh.gc(R.color.ratio)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEV SLOPE
|
||||||
|
data.overviewData.dsMaxSeries = LineGraphSeries(Array(dsMaxArray.size) { i -> dsMaxArray[i] }).also {
|
||||||
|
it.color = rh.gc(R.color.devslopepos)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
data.overviewData.dsMinSeries = LineGraphSeries(Array(dsMinArray.size) { i -> dsMinArray[i] }).also {
|
||||||
|
it.color = rh.gc(R.color.devslopeneg)
|
||||||
|
it.thickness = 3
|
||||||
|
}
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_IOB_AUTOSENS_DATA, 100, null))
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
|
import info.nightscout.androidaps.interfaces.Loop
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
class PreparePredictionsWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
|
@Inject lateinit var overviewData: OverviewData
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
@Inject lateinit var config: Config
|
||||||
|
@Inject lateinit var nsDeviceStatus: NSDeviceStatus
|
||||||
|
@Inject lateinit var loop: Loop
|
||||||
|
@Inject lateinit var overviewMenus: OverviewMenus
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PreparePredictionsData(
|
||||||
|
val overviewData: OverviewData
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as PreparePredictionsData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
val apsResult = if (config.APS) loop.lastRun?.constraintsProcessed else nsDeviceStatus.getAPSResult(injector)
|
||||||
|
val predictionsAvailable = if (config.APS) loop.lastRun?.request?.hasPredictions == true else config.NSCLIENT
|
||||||
|
val menuChartSettings = overviewMenus.setting
|
||||||
|
// align to hours
|
||||||
|
val calendar = Calendar.getInstance().also {
|
||||||
|
it.timeInMillis = System.currentTimeMillis()
|
||||||
|
it[Calendar.MILLISECOND] = 0
|
||||||
|
it[Calendar.SECOND] = 0
|
||||||
|
it[Calendar.MINUTE] = 0
|
||||||
|
it.add(Calendar.HOUR, 1)
|
||||||
|
}
|
||||||
|
if (predictionsAvailable && apsResult != null && menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal]) {
|
||||||
|
var predictionHours = (ceil(apsResult.latestPredictionsTime - System.currentTimeMillis().toDouble()) / (60 * 60 * 1000)).toInt()
|
||||||
|
predictionHours = min(2, predictionHours)
|
||||||
|
predictionHours = max(0, predictionHours)
|
||||||
|
val hoursToFetch = data.overviewData.rangeToDisplay - predictionHours
|
||||||
|
data.overviewData.toTime = calendar.timeInMillis + 100000 // little bit more to avoid wrong rounding - GraphView specific
|
||||||
|
data.overviewData.fromTime = data.overviewData.toTime - T.hours(hoursToFetch.toLong()).msecs()
|
||||||
|
data.overviewData.endTime = data.overviewData.toTime + T.hours(predictionHours.toLong()).msecs()
|
||||||
|
} else {
|
||||||
|
data.overviewData.toTime = calendar.timeInMillis + 100000 // little bit more to avoid wrong rounding - GraphView specific
|
||||||
|
data.overviewData.fromTime = data.overviewData.toTime - T.hours(data.overviewData.rangeToDisplay.toLong()).msecs()
|
||||||
|
data.overviewData.endTime = data.overviewData.toTime
|
||||||
|
}
|
||||||
|
|
||||||
|
val bgListArray: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||||
|
val predictions: MutableList<GlucoseValueDataPoint>? = apsResult?.predictions
|
||||||
|
?.map { bg -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh) }
|
||||||
|
?.toMutableList()
|
||||||
|
if (predictions != null) {
|
||||||
|
predictions.sortWith { o1: GlucoseValueDataPoint, o2: GlucoseValueDataPoint -> o1.x.compareTo(o2.x) }
|
||||||
|
for (prediction in predictions) if (prediction.data.value >= 40) bgListArray.add(prediction)
|
||||||
|
}
|
||||||
|
data.overviewData.predictionsGraphSeries = PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] })
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import com.jjoe64.graphview.series.DataPoint
|
||||||
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
|
import info.nightscout.androidaps.extensions.target
|
||||||
|
import info.nightscout.androidaps.interfaces.Loop
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class PrepareTemporaryTargetDataWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var loop: Loop
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrepareTemporaryTargetData(
|
||||||
|
val overviewData: OverviewData
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as PrepareTemporaryTargetData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_TEMPORARY_TARGET_DATA, 0, null))
|
||||||
|
val profile = profileFunction.getProfile() ?: return Result.failure(workDataOf("Error" to "missing profile"))
|
||||||
|
val units = profileFunction.getUnits()
|
||||||
|
var toTime = data.overviewData.toTime
|
||||||
|
val targetsSeriesArray: MutableList<DataPoint> = ArrayList()
|
||||||
|
var lastTarget = -1.0
|
||||||
|
loop.lastRun?.constraintsProcessed?.let { toTime = max(it.latestPredictionsTime, toTime) }
|
||||||
|
var time = data.overviewData.fromTime
|
||||||
|
while (time < toTime) {
|
||||||
|
val progress = (time - data.overviewData.fromTime).toDouble() / (data.overviewData.toTime - data.overviewData.fromTime) * 100.0
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_TEMPORARY_TARGET_DATA, progress.toInt(), null))
|
||||||
|
val tt = repository.getTemporaryTargetActiveAt(time).blockingGet()
|
||||||
|
val value: Double = if (tt is ValueWrapper.Existing) {
|
||||||
|
Profile.fromMgdlToUnits(tt.value.target(), units)
|
||||||
|
} else {
|
||||||
|
Profile.fromMgdlToUnits((profile.getTargetLowMgdl(time) + profile.getTargetHighMgdl(time)) / 2, units)
|
||||||
|
}
|
||||||
|
if (lastTarget != value) {
|
||||||
|
if (lastTarget != -1.0) targetsSeriesArray.add(DataPoint(time.toDouble(), lastTarget))
|
||||||
|
targetsSeriesArray.add(DataPoint(time.toDouble(), value))
|
||||||
|
}
|
||||||
|
lastTarget = value
|
||||||
|
time += 5 * 60 * 1000L
|
||||||
|
}
|
||||||
|
// final point
|
||||||
|
targetsSeriesArray.add(DataPoint(toTime.toDouble(), lastTarget))
|
||||||
|
// create series
|
||||||
|
data.overviewData.temporaryTargetSeries = LineGraphSeries(Array(targetsSeriesArray.size) { i -> targetsSeriesArray[i] }).also {
|
||||||
|
it.isDrawBackground = false
|
||||||
|
it.color = rh.gc(R.color.tempTargetBackground)
|
||||||
|
it.thickness = 2
|
||||||
|
}
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_TEMPORARY_TARGET_DATA, 100, null))
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import androidx.work.workDataOf
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.Bolus
|
||||||
|
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||||
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
|
import info.nightscout.androidaps.receivers.DataWorker
|
||||||
|
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.androidaps.utils.Translator
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class PrepareTreatmentsDataWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var dataWorker: DataWorker
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var rh: ResourceHelper
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
@Inject lateinit var translator: Translator
|
||||||
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrepareTreatmentsData(
|
||||||
|
val overviewData: OverviewData
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
val data = dataWorker.pickupObject(inputData.getLong(DataWorker.STORE_KEY, -1)) as PrepareTreatmentsData?
|
||||||
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_TREATMENTS_DATA, 0, null))
|
||||||
|
data.overviewData.maxTreatmentsValue = 0.0
|
||||||
|
val filteredTreatments: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||||
|
repository.getBolusesDataFromTimeToTime(data.overviewData.fromTime, data.overviewData.endTime, true).blockingGet()
|
||||||
|
.map { BolusDataPoint(it, rh, activePlugin, defaultValueHelper) }
|
||||||
|
.filter { it.data.type == Bolus.Type.NORMAL || it.data.type == Bolus.Type.SMB }
|
||||||
|
.forEach {
|
||||||
|
it.y = getNearestBg(data.overviewData, it.x.toLong())
|
||||||
|
filteredTreatments.add(it)
|
||||||
|
}
|
||||||
|
repository.getCarbsDataFromTimeToTimeExpanded(data.overviewData.fromTime, data.overviewData.endTime, true).blockingGet()
|
||||||
|
.map { CarbsDataPoint(it, rh) }
|
||||||
|
.forEach {
|
||||||
|
it.y = getNearestBg(data.overviewData, it.x.toLong())
|
||||||
|
filteredTreatments.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProfileSwitch
|
||||||
|
repository.getEffectiveProfileSwitchDataFromTimeToTime(data.overviewData.fromTime, data.overviewData.endTime, true).blockingGet()
|
||||||
|
.map { EffectiveProfileSwitchDataPoint(it, rh) }
|
||||||
|
.forEach(filteredTreatments::add)
|
||||||
|
|
||||||
|
// OfflineEvent
|
||||||
|
repository.getOfflineEventDataFromTimeToTime(data.overviewData.fromTime, data.overviewData.endTime, true).blockingGet()
|
||||||
|
.map {
|
||||||
|
TherapyEventDataPoint(
|
||||||
|
TherapyEvent(timestamp = it.timestamp, duration = it.duration, type = TherapyEvent.Type.APS_OFFLINE, glucoseUnit = TherapyEvent.GlucoseUnit.MMOL),
|
||||||
|
rh,
|
||||||
|
profileFunction,
|
||||||
|
translator
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.forEach(filteredTreatments::add)
|
||||||
|
|
||||||
|
// Extended bolus
|
||||||
|
if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
|
||||||
|
repository.getExtendedBolusDataFromTimeToTime(data.overviewData.fromTime, data.overviewData.endTime, true).blockingGet()
|
||||||
|
.map { ExtendedBolusDataPoint(it, rh) }
|
||||||
|
.filter { it.duration != 0L }
|
||||||
|
.forEach {
|
||||||
|
it.y = getNearestBg(data.overviewData, it.x.toLong())
|
||||||
|
filteredTreatments.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Careportal
|
||||||
|
repository.compatGetTherapyEventDataFromToTime(data.overviewData.fromTime - T.hours(6).msecs(), data.overviewData.endTime).blockingGet()
|
||||||
|
.map { TherapyEventDataPoint(it, rh, profileFunction, translator) }
|
||||||
|
.filterTimeframe(data.overviewData.fromTime, data.overviewData.endTime)
|
||||||
|
.forEach {
|
||||||
|
if (it.y == 0.0) it.y = getNearestBg(data.overviewData, it.x.toLong())
|
||||||
|
filteredTreatments.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase maxY if a treatment forces it's own height that's higher than a BG value
|
||||||
|
filteredTreatments.map { it.y }
|
||||||
|
.maxOrNull()
|
||||||
|
?.let(::addUpperChartMargin)
|
||||||
|
?.let { data.overviewData.maxTreatmentsValue = maxOf(data.overviewData.maxTreatmentsValue, it) }
|
||||||
|
|
||||||
|
data.overviewData.treatmentsSeries = PointsWithLabelGraphSeries(filteredTreatments.toTypedArray())
|
||||||
|
|
||||||
|
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_TREATMENTS_DATA, 100, null))
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addUpperChartMargin(maxBgValue: Double) =
|
||||||
|
if (profileFunction.getUnits() == GlucoseUnit.MGDL) Round.roundTo(maxBgValue, 40.0) + 80 else Round.roundTo(maxBgValue, 2.0) + 4
|
||||||
|
|
||||||
|
private fun getNearestBg(overviewData: OverviewData, date: Long): Double {
|
||||||
|
overviewData.bgReadingsArray.let { bgReadingsArray ->
|
||||||
|
for (reading in bgReadingsArray) {
|
||||||
|
if (reading.timestamp > date) continue
|
||||||
|
return Profile.fromMgdlToUnits(reading.value, profileFunction.getUnits())
|
||||||
|
}
|
||||||
|
return if (bgReadingsArray.isNotEmpty()) Profile.fromMgdlToUnits(bgReadingsArray[0].value, profileFunction.getUnits())
|
||||||
|
else Profile.fromMgdlToUnits(100.0, profileFunction.getUnits())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <E : DataPointWithLabelInterface> List<E>.filterTimeframe(fromTime: Long, endTime: Long): List<E> =
|
||||||
|
filter { it.x + it.duration >= fromTime && it.x <= endTime }
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewGraph
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class UpdateGraphWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
@Inject lateinit var overviewPlugin: OverviewPlugin
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
if (inputData.getString(CalculationWorkflow.JOB) == CalculationWorkflow.MAIN_CALCULATION)
|
||||||
|
overviewPlugin.overviewBus.send(EventUpdateOverviewGraph("UpdateGraphWorker"))
|
||||||
|
else
|
||||||
|
rxBus.send(EventUpdateOverviewGraph("UpdateGraphWorker"))
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package info.nightscout.androidaps.workflow
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewIobCob
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewSensitivity
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class UpdateIobCobSensWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
@Inject lateinit var overviewPlugin: OverviewPlugin
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
overviewPlugin.overviewBus.send(EventUpdateOverviewIobCob("UpdateIobCobSensWorker"))
|
||||||
|
overviewPlugin.overviewBus.send(EventUpdateOverviewSensitivity("UpdateIobCobSensWorker"))
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,6 +63,17 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:indeterminate="false"
|
||||||
|
android:max="100"
|
||||||
|
android:progress="100" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -88,13 +99,6 @@
|
||||||
android:paddingTop="5dp"
|
android:paddingTop="5dp"
|
||||||
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
|
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/overview_iobcalculationprogess"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:textSize="15sp" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -30,6 +30,8 @@ class AbstractSensitivityPluginTest : TestBase() {
|
||||||
override val id: Sensitivity.SensitivityType
|
override val id: Sensitivity.SensitivityType
|
||||||
get() = Sensitivity.SensitivityType.UNKNOWN
|
get() = Sensitivity.SensitivityType.UNKNOWN
|
||||||
|
|
||||||
|
override fun maxAbsorptionHours(): Double = 8.0
|
||||||
|
|
||||||
override fun configuration(): JSONObject = JSONObject()
|
override fun configuration(): JSONObject = JSONObject()
|
||||||
|
|
||||||
override fun applyConfiguration(configuration: JSONObject) {}
|
override fun applyConfiguration(configuration: JSONObject) {}
|
||||||
|
|
|
@ -7,7 +7,11 @@ import android.os.SystemClock
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||||
import info.nightscout.androidaps.automation.R
|
import info.nightscout.androidaps.automation.R
|
||||||
import info.nightscout.androidaps.events.*
|
import info.nightscout.androidaps.events.EventBTChange
|
||||||
|
import info.nightscout.androidaps.events.EventChargingState
|
||||||
|
import info.nightscout.androidaps.events.EventLocationChange
|
||||||
|
import info.nightscout.androidaps.events.EventNetworkChange
|
||||||
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
|
@ -33,7 +37,6 @@ import org.json.JSONObject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
@OpenForTesting
|
@OpenForTesting
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@ -127,10 +130,6 @@ class AutomationPlugin @Inject constructor(
|
||||||
.toObservable(EventNetworkChange::class.java)
|
.toObservable(EventNetworkChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ processActions() }, fabricPrivacy::logException)
|
.subscribe({ processActions() }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ processActions() }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventBTChange::class.java)
|
.toObservable(EventBTChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
|
@ -150,7 +149,7 @@ class AutomationPlugin @Inject constructor(
|
||||||
|
|
||||||
private fun storeToSP() {
|
private fun storeToSP() {
|
||||||
val array = JSONArray()
|
val array = JSONArray()
|
||||||
val iterator = ArrayList<AutomationEvent>(automationEvents).iterator()
|
val iterator = ArrayList(automationEvents).iterator()
|
||||||
try {
|
try {
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val event = iterator.next()
|
val event = iterator.next()
|
||||||
|
|
|
@ -38,6 +38,7 @@ ActionsTestBase : TestBaseWithProfile() {
|
||||||
override var enabled: Boolean
|
override var enabled: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
set(_) {}
|
set(_) {}
|
||||||
|
override var lastBgTriggeredRun: Long = 0
|
||||||
|
|
||||||
override fun invoke(initiator: String, allowNotification: Boolean, tempBasalFallback: Boolean) {}
|
override fun invoke(initiator: String, allowNotification: Boolean, tempBasalFallback: Boolean) {}
|
||||||
override fun acceptChangeRequest() {}
|
override fun acceptChangeRequest() {}
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
package info.nightscout.androidaps.events
|
package info.nightscout.androidaps.events
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
import info.nightscout.androidaps.events.EventLoop
|
|
||||||
|
|
||||||
class EventAutosensCalculationFinished(val cause: Event?) : EventLoop()
|
class EventAutosensCalculationFinished(val cause: Event?) : EventLoop()
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
package info.nightscout.androidaps.events
|
package info.nightscout.androidaps.events
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
|
||||||
|
|
||||||
class EventDanaRSyncStatus(var message: String) : Event()
|
class EventDanaRSyncStatus(var message: String) : Event()
|
|
@ -5,6 +5,7 @@ import android.os.Looper
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
|
||||||
fun Boolean.toVisibility() = if (this) View.VISIBLE else View.GONE
|
fun Boolean.toVisibility() = if (this) View.VISIBLE else View.GONE
|
||||||
|
fun Boolean.toVisibilityKeepSpace() = if (this) View.VISIBLE else View.INVISIBLE
|
||||||
|
|
||||||
fun runOnUiThread(theRunnable: Runnable?) = theRunnable?.let {
|
fun runOnUiThread(theRunnable: Runnable?) = theRunnable?.let {
|
||||||
Handler(Looper.getMainLooper()).post(it)
|
Handler(Looper.getMainLooper()).post(it)
|
||||||
|
|
|
@ -52,6 +52,12 @@ interface ActivePlugin {
|
||||||
*/
|
*/
|
||||||
val activeSafety: Safety
|
val activeSafety: Safety
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently selected Safety plugin
|
||||||
|
* Always IobCobCalculatorPlugin
|
||||||
|
*/
|
||||||
|
val activeIobCobCalculator: IobCobCalculator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of all registered plugins
|
* List of all registered plugins
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,6 +28,8 @@ interface Loop {
|
||||||
val isDisconnected: Boolean
|
val isDisconnected: Boolean
|
||||||
var enabled: Boolean
|
var enabled: Boolean
|
||||||
|
|
||||||
|
var lastBgTriggeredRun: Long
|
||||||
|
|
||||||
fun invoke(initiator: String, allowNotification: Boolean, tempBasalFallback: Boolean = false)
|
fun invoke(initiator: String, allowNotification: Boolean, tempBasalFallback: Boolean = false)
|
||||||
|
|
||||||
fun acceptChangeRequest()
|
fun acceptChangeRequest()
|
||||||
|
|
|
@ -4,6 +4,5 @@ import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
|
||||||
interface Overview : ConfigExportImport {
|
interface Overview : ConfigExportImport {
|
||||||
|
|
||||||
fun refreshLoop(from: String)
|
|
||||||
val overviewBus: RxBus
|
val overviewBus: RxBus
|
||||||
}
|
}
|
|
@ -20,6 +20,7 @@ interface Sensitivity : ConfigExportImport {
|
||||||
|
|
||||||
val id: SensitivityType
|
val id: SensitivityType
|
||||||
fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult
|
fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult
|
||||||
|
fun maxAbsorptionHours(): Double
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
|
|
@ -234,6 +234,9 @@
|
||||||
<color name="mdtp_button_selected">#33969696</color>
|
<color name="mdtp_button_selected">#33969696</color>
|
||||||
<color name="plastic">#EBEBEA</color>
|
<color name="plastic">#EBEBEA</color>
|
||||||
|
|
||||||
|
<color name="textAppearancemediumLight">#000000</color>
|
||||||
|
<color name="textAppearancemediumDark">#B3FFFFFF</color>
|
||||||
|
|
||||||
<!-- dash and eros colors -->
|
<!-- dash and eros colors -->
|
||||||
<color name="omni_yellow">#FFFF00</color>
|
<color name="omni_yellow">#FFFF00</color>
|
||||||
<color name="omni_cyan">#00FFFF</color>
|
<color name="omni_cyan">#00FFFF</color>
|
||||||
|
|
|
@ -225,6 +225,7 @@
|
||||||
<item name="activityColor">@color/activity</item>
|
<item name="activityColor">@color/activity</item>
|
||||||
<!-- CardView specific colors -->
|
<!-- CardView specific colors -->
|
||||||
<item name="strokeColor">@color/plastic_grey</item>
|
<item name="strokeColor">@color/plastic_grey</item>
|
||||||
|
<item name="textAppearancemediumColor">@color/textAppearancemediumDark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.MaterialComponents.DayNight.DarkActionBar" parent="Theme.MaterialComponents.DayNight.Bridge"/>
|
<style name="Theme.MaterialComponents.DayNight.DarkActionBar" parent="Theme.MaterialComponents.DayNight.Bridge"/>
|
||||||
|
|
|
@ -205,4 +205,5 @@
|
||||||
<attr name="activityColor" format="reference|color" />
|
<attr name="activityColor" format="reference|color" />
|
||||||
<!-- CardView specific colors -->
|
<!-- CardView specific colors -->
|
||||||
<attr name="strokeColor" format="reference|color" />
|
<attr name="strokeColor" format="reference|color" />
|
||||||
|
<attr name="textAppearancemediumColor" format="reference|color" />
|
||||||
</resources>
|
</resources>
|
|
@ -238,6 +238,9 @@
|
||||||
<color name="mdtp_button_selected">#33969696</color>
|
<color name="mdtp_button_selected">#33969696</color>
|
||||||
<color name="plastic">#EBEBEA</color>
|
<color name="plastic">#EBEBEA</color>
|
||||||
|
|
||||||
|
<color name="textAppearancemediumLight">#000000</color>
|
||||||
|
<color name="textAppearancemediumDark">#B3FFFFFF</color>
|
||||||
|
|
||||||
<!-- dash and eros colors -->
|
<!-- dash and eros colors -->
|
||||||
<color name="omni_yellow">#FFFF00</color>
|
<color name="omni_yellow">#FFFF00</color>
|
||||||
<color name="omni_cyan">#00FFFF</color>
|
<color name="omni_cyan">#00FFFF</color>
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
<!-- BG source temp button -->
|
<!-- BG source temp button -->
|
||||||
<item name="setTempButton">@color/colorSetTempButton</item>
|
<item name="setTempButton">@color/colorSetTempButton</item>
|
||||||
<!-- Card Item-->
|
<!-- Card Item-->
|
||||||
<item name="cardItemBackgroundColor">@color/cardColorBackground</item>
|
<item name="cardItemBackgroundColor">?attr/colorSurface</item>
|
||||||
<!-- Exercise -->
|
<!-- Exercise -->
|
||||||
<item name="exerciseColor">@color/exercise</item>
|
<item name="exerciseColor">@color/exercise</item>
|
||||||
<!-- BG low -->
|
<!-- BG low -->
|
||||||
|
@ -233,6 +233,7 @@
|
||||||
<item name="activityColor">@color/activity</item>
|
<item name="activityColor">@color/activity</item>
|
||||||
<!-- CardView specific colors -->
|
<!-- CardView specific colors -->
|
||||||
<item name="strokeColor">@color/plastic_grey</item>
|
<item name="strokeColor">@color/plastic_grey</item>
|
||||||
|
<item name="textAppearancemediumColor">@color/textAppearancemediumLight</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.MaterialComponents.DayNight.DarkActionBar" parent="Theme.MaterialComponents.DayNight.Bridge"/>
|
<style name="Theme.MaterialComponents.DayNight.DarkActionBar" parent="Theme.MaterialComponents.DayNight.Bridge"/>
|
||||||
|
|
|
@ -27,7 +27,7 @@ android {
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
jniLibs.srcDirs = ['libs']
|
jniLibs.srcDirs = ['src/main/jniLibs']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,8 +111,8 @@ dependencies {
|
||||||
implementation(files('libs/wearpreferenceactivity-0.5.0.aar'))
|
implementation(files('libs/wearpreferenceactivity-0.5.0.aar'))
|
||||||
implementation('com.github.lecho:hellocharts-library:1.5.8@aar')
|
implementation('com.github.lecho:hellocharts-library:1.5.8@aar')
|
||||||
|
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.1'
|
||||||
implementation "androidx.core:core-ktx:$core_version"
|
implementation "androidx.core:core-ktx:$core_version"
|
||||||
implementation "androidx.wear.tiles:tiles:1.0.1"
|
implementation "androidx.wear.tiles:tiles:1.0.1"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
|
|
Loading…
Reference in a new issue