diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 18750bfda8..77b68adf4a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,7 +68,8 @@
-
+
+
diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt
index 4fa4fbe4b9..42559a543b 100644
--- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt
+++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt
@@ -27,18 +27,14 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.joanzapata.iconify.Iconify
import com.joanzapata.iconify.fonts.FontAwesomeModule
import dev.doubledot.doki.ui.DokiActivity
-import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
-import info.nightscout.androidaps.activities.PreferencesActivity
-import info.nightscout.androidaps.activities.ProfileHelperActivity
-import info.nightscout.androidaps.activities.SingleFragmentActivity
-import info.nightscout.androidaps.activities.StatsActivity
+import info.nightscout.androidaps.activities.*
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.databinding.ActivityMainBinding
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.events.EventRebuildTabs
-import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
+import info.nightscout.androidaps.activities.HistoryBrowseActivity
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.IconsProvider
@@ -291,6 +287,11 @@ class MainActivity : NoSplashAppCompatActivity() {
return true
}
+ R.id.nav_treatments -> {
+ startActivity(Intent(this, TreatmentsActivity::class.java))
+ return true
+ }
+
R.id.nav_setupwizard -> {
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, {
startActivity(Intent(this, SetupWizardActivity::class.java))
diff --git a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt
new file mode 100644
index 0000000000..6b0be2cc68
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt
@@ -0,0 +1,391 @@
+package info.nightscout.androidaps.activities
+
+import android.annotation.SuppressLint
+import android.app.DatePickerDialog
+import android.graphics.Color
+import android.os.Bundle
+import android.util.DisplayMetrics
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import android.widget.TextView
+import com.jjoe64.graphview.GraphView
+import dagger.android.HasAndroidInjector
+import info.nightscout.androidaps.R
+import info.nightscout.androidaps.database.AppRepository
+import info.nightscout.androidaps.databinding.ActivityHistorybrowseBinding
+import info.nightscout.androidaps.events.EventAutosensCalculationFinished
+import info.nightscout.androidaps.events.EventCustomCalculationFinished
+import info.nightscout.androidaps.events.EventRefreshOverview
+import info.nightscout.androidaps.extensions.toVisibility
+import info.nightscout.androidaps.interfaces.ActivePlugin
+import info.nightscout.androidaps.interfaces.Config
+import info.nightscout.androidaps.interfaces.ProfileFunction
+import info.nightscout.androidaps.logging.AAPSLogger
+import info.nightscout.androidaps.logging.LTag
+import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
+import info.nightscout.androidaps.plugins.bus.RxBusWrapper
+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.graphData.GraphData
+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.sensitivity.SensitivityAAPSPlugin
+import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
+import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
+import info.nightscout.androidaps.utils.*
+import info.nightscout.androidaps.utils.buildHelper.BuildHelper
+import info.nightscout.androidaps.utils.rx.AapsSchedulers
+import info.nightscout.androidaps.utils.sharedPreferences.SP
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.rxkotlin.plusAssign
+import java.util.*
+import javax.inject.Inject
+import kotlin.math.min
+
+class HistoryBrowseActivity : NoSplashAppCompatActivity() {
+
+ @Inject lateinit var injector: HasAndroidInjector
+ @Inject lateinit var aapsLogger: AAPSLogger
+ @Inject lateinit var aapsSchedulers: AapsSchedulers
+ @Inject lateinit var rxBus: RxBusWrapper
+ @Inject lateinit var sp: SP
+ @Inject lateinit var profileFunction: ProfileFunction
+ @Inject lateinit var defaultValueHelper: DefaultValueHelper
+ @Inject lateinit var activePlugin: ActivePlugin
+ @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 fabricPrivacy: FabricPrivacy
+ @Inject lateinit var overviewMenus: OverviewMenus
+ @Inject lateinit var dateUtil: DateUtil
+ @Inject lateinit var config: Config
+ @Inject lateinit var loopPlugin: LoopPlugin
+ @Inject lateinit var nsDeviceStatus: NSDeviceStatus
+ @Inject lateinit var translator: Translator
+
+ private val disposable = CompositeDisposable()
+
+ private val secondaryGraphs = ArrayList()
+ private val secondaryGraphsLabel = ArrayList()
+
+ private var axisWidth: Int = 0
+ private var rangeToDisplay = 24 // for graph
+// private var start: Long = 0
+
+ private lateinit var iobCobCalculator: IobCobCalculatorPlugin
+ private lateinit var overviewData: OverviewData
+
+ private lateinit var binding: ActivityHistorybrowseBinding
+ private var destroyed = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityHistorybrowseBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ // We don't want to use injected singletons but own instance working on top of different data
+ iobCobCalculator = IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction, activePlugin, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil, repository)
+ overviewData = OverviewData(injector, aapsLogger, resourceHelper, dateUtil, sp, activePlugin, defaultValueHelper, profileFunction, config, loopPlugin, nsDeviceStatus, repository, overviewMenus, iobCobCalculator, translator)
+
+ binding.left.setOnClickListener {
+ setTime(overviewData.fromTime - T.hours(rangeToDisplay.toLong()).msecs())
+ loadAll("onClickLeft")
+ }
+ binding.right.setOnClickListener {
+ setTime(overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs())
+ loadAll("onClickRight")
+ }
+ binding.end.setOnClickListener {
+ setTime(dateUtil.now())
+ loadAll("onClickEnd")
+ }
+ binding.zoom.setOnClickListener {
+ rangeToDisplay += 6
+ rangeToDisplay = if (rangeToDisplay > 24) 6 else rangeToDisplay
+ setTime(overviewData.fromTime)
+ loadAll("rangeChange")
+ }
+ binding.zoom.setOnLongClickListener {
+ Calendar.getInstance().also { calendar ->
+ calendar.timeInMillis = overviewData.fromTime
+ calendar[Calendar.MILLISECOND] = 0
+ calendar[Calendar.SECOND] = 0
+ calendar[Calendar.MINUTE] = 0
+ calendar[Calendar.HOUR_OF_DAY] = 0
+ setTime(calendar.timeInMillis)
+ }
+ loadAll("onLongClickZoom")
+ true
+ }
+
+ // create an OnDateSetListener
+ val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
+ Calendar.getInstance().also { calendar ->
+ calendar.timeInMillis = overviewData.fromTime
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = monthOfYear
+ calendar[Calendar.DAY_OF_MONTH] = dayOfMonth
+ calendar[Calendar.MILLISECOND] = 0
+ calendar[Calendar.SECOND] = 0
+ calendar[Calendar.MINUTE] = 0
+ calendar[Calendar.HOUR_OF_DAY] = 0
+ setTime(calendar.timeInMillis)
+ binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime)
+ }
+ loadAll("onClickDate")
+ }
+
+ binding.date.setOnClickListener {
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = overviewData.fromTime
+ DatePickerDialog(this, dateSetListener,
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH),
+ cal.get(Calendar.DAY_OF_MONTH)
+ ).show()
+ }
+
+ val dm = DisplayMetrics()
+ windowManager?.defaultDisplay?.getMetrics(dm)
+
+ 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 = resourceHelper.gc(R.color.graphgrid)
+ binding.bgGraph.gridLabelRenderer?.reloadStyles()
+ binding.bgGraph.gridLabelRenderer?.labelVerticalWidth = axisWidth
+
+ overviewMenus.setupChartMenu(binding.chartMenuButton)
+ prepareGraphsIfNeeded(overviewMenus.setting.size)
+ savedInstanceState?.let { bundle ->
+ rangeToDisplay = bundle.getInt("rangeToDisplay", 0)
+ overviewData.fromTime = bundle.getLong("start", 0)
+ overviewData.toTime = bundle.getLong("end", 0)
+ }
+ }
+
+ public override fun onPause() {
+ super.onPause()
+ disposable.clear()
+ iobCobCalculator.stopCalculation("onPause")
+ }
+
+ @Synchronized
+ override fun onDestroy() {
+ destroyed = true
+ super.onDestroy()
+ }
+
+ public override fun onResume() {
+ super.onResume()
+ disposable.add(rxBus
+ .toObservable(EventAutosensCalculationFinished::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({
+ // catch only events from iobCobCalculator
+ if (it.cause is EventCustomCalculationFinished)
+ refreshLoop("EventAutosensCalculationFinished")
+ }, fabricPrivacy::logException)
+ )
+ disposable.add(rxBus
+ .toObservable(EventIobCalculationProgress::class.java)
+ .observeOn(aapsSchedulers.main)
+ .subscribe({
+ if (it.cause is EventCustomCalculationFinished)
+ binding.overviewIobcalculationprogess.text = it.progress
+ }, fabricPrivacy::logException)
+ )
+ disposable.add(rxBus
+ .toObservable(EventRefreshOverview::class.java)
+ .observeOn(aapsSchedulers.main)
+ .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) {
+ // set start of current day
+ setTime(dateUtil.now())
+ loadAll("onResume")
+ } else {
+ updateGUI("onResume")
+ }
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ outState.putInt("rangeToDisplay", rangeToDisplay)
+ outState.putLong("start", overviewData.fromTime)
+ outState.putLong("end", overviewData.toTime)
+
+ }
+
+ private fun prepareGraphsIfNeeded(numOfGraphs: Int) {
+ if (numOfGraphs != secondaryGraphs.size - 1) {
+ //aapsLogger.debug("New secondary graph count ${numOfGraphs-1}")
+ // rebuild needed
+ secondaryGraphs.clear()
+ secondaryGraphsLabel.clear()
+ binding.iobGraph.removeAllViews()
+ for (i in 1 until numOfGraphs) {
+ val relativeLayout = RelativeLayout(this)
+ relativeLayout.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+
+ val graph = GraphView(this)
+ graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, resourceHelper.dpToPx(15), 0, resourceHelper.dpToPx(10)) }
+ graph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
+ graph.gridLabelRenderer?.reloadStyles()
+ graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
+ graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
+ graph.gridLabelRenderer?.numVerticalLabels = 3
+ graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray
+ relativeLayout.addView(graph)
+
+ val label = TextView(this)
+ val layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(resourceHelper.dpToPx(30), resourceHelper.dpToPx(25), 0, 0) }
+ layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP)
+ layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
+ label.layoutParams = layoutParams
+ relativeLayout.addView(label)
+ secondaryGraphsLabel.add(label)
+
+ binding.iobGraph.addView(relativeLayout)
+ secondaryGraphs.add(graph)
+ }
+ }
+ }
+
+ @Suppress("SameParameterValue")
+ private fun loadAll(from: String) {
+ Thread {
+ overviewData.prepareBasalData(from)
+ overviewData.prepareTemporaryTargetData(from)
+ overviewData.prepareTreatmentsData(from)
+ rxBus.send(EventRefreshOverview(from))
+ aapsLogger.debug(LTag.UI, "loadAll $from finished")
+ runCalculation(from)
+ }.start()
+ }
+
+ private fun setTime(start: Long) {
+ Calendar.getInstance().also { calendar ->
+ calendar.timeInMillis = start
+ calendar[Calendar.MILLISECOND] = 0
+ calendar[Calendar.SECOND] = 0
+ calendar[Calendar.MINUTE] = 0
+ calendar[Calendar.HOUR_OF_DAY] = 0
+ overviewData.fromTime = calendar.timeInMillis
+ overviewData.toTime = overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs()
+ overviewData.endTime = overviewData.toTime
+ }
+ }
+
+ private fun runCalculation(from: String) {
+ Thread {
+ iobCobCalculator.stopCalculation(from)
+ iobCobCalculator.stopCalculationTrigger = false
+ iobCobCalculator.runCalculation(from, overviewData.toTime, bgDataReload = true, limitDataToOldestAvailable = false, cause = EventCustomCalculationFinished())
+ }.start()
+ }
+
+ @Volatile
+ var runningRefresh = false
+ private fun refreshLoop(from: String) {
+ if (runningRefresh) return
+ runningRefresh = true
+ overviewData.prepareIobAutosensData(from)
+ rxBus.send(EventRefreshOverview(from))
+ aapsLogger.debug(LTag.UI, "refreshLoop finished")
+ runningRefresh = false
+ }
+
+ @Suppress("UNUSED_PARAMETER")
+ @SuppressLint("SetTextI18n")
+ fun updateGUI(from: String) {
+ aapsLogger.debug(LTag.UI, "updateGui $from")
+
+ binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime)
+ binding.zoom.text = rangeToDisplay.toString()
+
+ val pump = activePlugin.activePump
+ val graphData = GraphData(injector, binding.bgGraph, overviewData)
+ val menuChartSettings = overviewMenus.setting
+ graphData.addInRangeArea(overviewData.fromTime, overviewData.endTime, defaultValueHelper.determineLowLine(), defaultValueHelper.determineHighLine())
+ graphData.addBgReadings(menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
+ if (buildHelper.isDev()) graphData.addBucketedData()
+ graphData.addTreatments()
+ if (menuChartSettings[0][OverviewMenus.CharType.ACT.ordinal])
+ graphData.addActivity(0.8)
+ if (pump.pumpDescription.isTempBasalCapable && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal])
+ graphData.addBasals()
+ graphData.addTargetLine()
+ graphData.addNowLine(dateUtil.now())
+
+ // set manual x bounds to have nice steps
+ graphData.setNumVerticalLabels()
+ graphData.formatAxis(overviewData.fromTime, overviewData.endTime)
+
+ graphData.performUpdate()
+
+ // 2nd graphs
+ prepareGraphsIfNeeded(menuChartSettings.size)
+ val secondaryGraphsData: ArrayList = ArrayList()
+
+ val now = System.currentTimeMillis()
+ for (g in 0 until min(secondaryGraphs.size, menuChartSettings.size + 1)) {
+ val secondGraphData = GraphData(injector, secondaryGraphs[g], overviewData)
+ var useABSForScale = false
+ var useIobForScale = false
+ var useCobForScale = false
+ var useDevForScale = false
+ var useRatioForScale = false
+ var useDSForScale = false
+ var useBGIForScale = false
+ when {
+ menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
+ menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
+ menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
+ menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
+ menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] -> useBGIForScale = true
+ menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = 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]
+
+ if (menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(useABSForScale, 1.0)
+ if (menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(useIobForScale, 1.0)
+ if (menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(useCobForScale, if (useCobForScale) 1.0 else 0.5)
+ if (menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(useDevForScale, 1.0)
+ if (menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]) secondGraphData.addMinusBGI(useBGIForScale, if (alignDevBgiScale) 1.0 else 0.8)
+ if (menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(useRatioForScale, if (useRatioForScale) 1.0 else 0.8)
+ if (menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(useDSForScale, 1.0)
+
+ // set manual x bounds to have nice steps
+ secondGraphData.formatAxis(overviewData.fromTime, overviewData.endTime)
+ secondGraphData.addNowLine(now)
+ secondaryGraphsData.add(secondGraphData)
+ }
+ for (g in 0 until min(secondaryGraphs.size, menuChartSettings.size + 1)) {
+ secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1)
+ secondaryGraphs[g].visibility = (
+ menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] ||
+ menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] ||
+ menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] ||
+ menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] ||
+ menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] ||
+ menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] ||
+ menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal]
+ ).toVisibility()
+ secondaryGraphsData[g].performUpdate()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/TreatmentsActivity.kt
similarity index 53%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/TreatmentsActivity.kt
index 9de459f622..4cd4ab559a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/TreatmentsActivity.kt
@@ -1,53 +1,28 @@
-package info.nightscout.androidaps.plugins.treatments
+package info.nightscout.androidaps.activities
import android.os.Bundle
-import android.view.LayoutInflater
import android.view.View
-import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
-import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R
+import info.nightscout.androidaps.activities.fragments.*
import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding
-import info.nightscout.androidaps.events.EventExtendedBolusChange
-import info.nightscout.androidaps.interfaces.ActivePlugin
-import info.nightscout.androidaps.interfaces.IobCobCalculator
-import info.nightscout.androidaps.plugins.bus.RxBusWrapper
-import info.nightscout.androidaps.plugins.treatments.fragments.*
-import info.nightscout.androidaps.utils.DateUtil
-import info.nightscout.androidaps.utils.FabricPrivacy
-import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.extensions.toVisibility
-import info.nightscout.androidaps.utils.resources.ResourceHelper
-import info.nightscout.androidaps.utils.rx.AapsSchedulers
-import io.reactivex.disposables.CompositeDisposable
-import io.reactivex.rxkotlin.plusAssign
+import info.nightscout.androidaps.interfaces.ActivePlugin
+import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import javax.inject.Inject
-class TreatmentsFragment : DaggerFragment() {
+class TreatmentsActivity : NoSplashAppCompatActivity() {
- @Inject lateinit var rxBus: RxBusWrapper
- @Inject lateinit var resourceHelper: ResourceHelper
- @Inject lateinit var fabricPrivacy: FabricPrivacy
- @Inject lateinit var activePlugin: ActivePlugin
- @Inject lateinit var iobCobCalculator: IobCobCalculator
- @Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var buildHelper: BuildHelper
- @Inject lateinit var dateUtil: DateUtil
+ @Inject lateinit var activePlugin: ActivePlugin
- private val disposable = CompositeDisposable()
+ private lateinit var binding: TreatmentsFragmentBinding
- private var _binding: TreatmentsFragmentBinding? = null
-
- // This property is only valid between onCreateView and
- // onDestroyView.
- private val binding get() = _binding!!
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
- TreatmentsFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = TreatmentsFragmentBinding.inflate(layoutInflater)
+ setContentView(binding.root)
binding.tempBasals.visibility = buildHelper.isEngineeringMode().toVisibility()
binding.extendedBoluses.visibility = (buildHelper.isEngineeringMode() && !activePlugin.activePump.isFakingTempsByExtendedBoluses).toVisibility()
@@ -84,33 +59,10 @@ class TreatmentsFragment : DaggerFragment() {
setBackgroundColorOnSelected(binding.treatments)
}
- @Synchronized
- override fun onResume() {
- super.onResume()
- disposable += rxBus
- .toObservable(EventExtendedBolusChange::class.java)
- .observeOn(aapsSchedulers.main)
- .subscribe({ updateGui() }, fabricPrivacy::logException)
- updateGui()
- }
-
- @Synchronized
- override fun onPause() {
- super.onPause()
- disposable.clear()
- }
-
- @Synchronized
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
- }
-
private fun setFragment(selectedFragment: Fragment) {
- childFragmentManager.beginTransaction()
- .replace(R.id.fragment_container, selectedFragment) // f2_container is your FrameLayout container
- .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
- .addToBackStack(null)
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.fragment_container, selectedFragment)
+ .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit()
}
@@ -125,8 +77,4 @@ class TreatmentsFragment : DaggerFragment() {
selected.setBackgroundColor(resourceHelper.gc(R.color.tabBgColorSelected))
}
- private fun updateGui() {
- if (_binding == null) return
- binding.extendedBoluses.visibility = (activePlugin.activePump.pumpDescription.isExtendedBolusCapable || iobCobCalculator.getExtendedBolus(dateUtil.now()) != null).toVisibility()
- }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsBolusCarbsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt
similarity index 99%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsBolusCarbsFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt
index 2ba8978ea8..4b5dc48e2a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsBolusCarbsFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt
@@ -1,4 +1,4 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.activities.fragments
import android.graphics.Paint
import android.os.Bundle
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt
similarity index 98%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt
index ce75d4dc3c..f3eb9e551f 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt
@@ -1,4 +1,4 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.activities.fragments
import android.graphics.Paint
import android.os.Bundle
@@ -25,7 +25,7 @@ import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
-import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsCareportalFragment.RecyclerViewAdapter.TherapyEventsViewHolder
+import info.nightscout.androidaps.activities.fragments.TreatmentsCareportalFragment.RecyclerViewAdapter.TherapyEventsViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsExtendedBolusesFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt
similarity index 97%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsExtendedBolusesFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt
index 36b0a8a69a..d5dfec5f6c 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsExtendedBolusesFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt
@@ -1,4 +1,4 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.activities.fragments
import android.annotation.SuppressLint
import android.content.DialogInterface
@@ -30,7 +30,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
-import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsExtendedBolusesFragment.RecyclerViewAdapter.ExtendedBolusesViewHolder
+import info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment.RecyclerViewAdapter.ExtendedBolusesViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt
similarity index 98%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt
index 796c811f0f..151b37234f 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt
@@ -1,4 +1,4 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.activities.fragments
import android.graphics.Paint
import android.os.Bundle
@@ -30,7 +30,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHi
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
-import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsProfileSwitchFragment.RecyclerProfileViewAdapter.ProfileSwitchViewHolder
+import info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFragment.RecyclerProfileViewAdapter.ProfileSwitchViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTempTargetFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt
similarity index 98%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTempTargetFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt
index d603263fc1..16e8a5ae32 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTempTargetFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt
@@ -1,4 +1,4 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.activities.fragments
import android.annotation.SuppressLint
import android.content.DialogInterface
@@ -29,7 +29,7 @@ import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
-import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsTempTargetFragment.RecyclerViewAdapter.TempTargetsViewHolder
+import info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment.RecyclerViewAdapter.TempTargetsViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTemporaryBasalsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt
similarity index 98%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTemporaryBasalsFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt
index c9bda0e311..590fef204f 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTemporaryBasalsFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt
@@ -1,4 +1,4 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.activities.fragments
import android.content.DialogInterface
import android.graphics.Paint
@@ -36,7 +36,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
-import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsTemporaryBasalsFragment.RecyclerViewAdapter.TempBasalsViewHolder
+import info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment.RecyclerViewAdapter.TempBasalsViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsUserEntryFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsUserEntryFragment.kt
similarity index 99%
rename from app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsUserEntryFragment.kt
rename to app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsUserEntryFragment.kt
index 9bbc46d63b..b0936580ae 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsUserEntryFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsUserEntryFragment.kt
@@ -1,4 +1,4 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.activities.fragments
import android.os.Bundle
import android.view.LayoutInflater
diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt
index 95e0888b79..08e25f456f 100644
--- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt
+++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt
@@ -4,7 +4,7 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.MainActivity
import info.nightscout.androidaps.activities.*
-import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
+import info.nightscout.androidaps.activities.HistoryBrowseActivity
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
@@ -15,6 +15,7 @@ import info.nightscout.androidaps.setupwizard.SetupWizardActivity
@Suppress("unused")
abstract class ActivitiesModule {
+ @ContributesAndroidInjector abstract fun contributesTreatmentsActivity(): TreatmentsActivity
@ContributesAndroidInjector abstract fun contributesHistoryBrowseActivity(): HistoryBrowseActivity
@ContributesAndroidInjector abstract fun contributesLogSettingActivity(): LogSettingActivity
@ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity
diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt
index 60eb3ace15..84e4ef80fb 100644
--- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt
+++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt
@@ -31,8 +31,7 @@ import info.nightscout.androidaps.plugins.insulin.InsulinFragment
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
import info.nightscout.androidaps.plugins.source.BGSourceFragment
-import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
-import info.nightscout.androidaps.plugins.treatments.fragments.*
+import info.nightscout.androidaps.activities.fragments.*
import info.nightscout.androidaps.utils.protection.PasswordCheck
@Module
@@ -61,7 +60,6 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
- @ContributesAndroidInjector abstract fun contributesTreatmentsFragment(): TreatmentsFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusCarbsFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment
@ContributesAndroidInjector abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment
diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt
index 9d4e34a89b..214847aff9 100644
--- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt
+++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt
@@ -27,7 +27,6 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
-import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.CommandQueue
import info.nightscout.androidaps.utils.*
@@ -47,7 +46,6 @@ class CarbsDialog : DialogFragmentWithDate() {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var constraintChecker: ConstraintChecker
@Inject lateinit var defaultValueHelper: DefaultValueHelper
- @Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var uel: UserEntryLogger
diff --git a/app/src/main/java/info/nightscout/androidaps/historyBrowser/HistoryBrowseActivity.kt b/app/src/main/java/info/nightscout/androidaps/historyBrowser/HistoryBrowseActivity.kt
deleted file mode 100644
index 1abda3295f..0000000000
--- a/app/src/main/java/info/nightscout/androidaps/historyBrowser/HistoryBrowseActivity.kt
+++ /dev/null
@@ -1,379 +0,0 @@
-package info.nightscout.androidaps.historyBrowser
-
-import android.app.DatePickerDialog
-import android.graphics.Color
-import android.os.Bundle
-import android.util.DisplayMetrics
-import android.view.ViewGroup
-import android.widget.LinearLayout
-import android.widget.RelativeLayout
-import android.widget.TextView
-import androidx.lifecycle.lifecycleScope
-import com.jjoe64.graphview.GraphView
-import dagger.android.HasAndroidInjector
-import info.nightscout.androidaps.R
-import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
-import info.nightscout.androidaps.databinding.ActivityHistorybrowseBinding
-import info.nightscout.androidaps.events.EventAutosensCalculationFinished
-import info.nightscout.androidaps.events.EventCustomCalculationFinished
-import info.nightscout.androidaps.events.EventRefreshOverview
-import info.nightscout.androidaps.extensions.toVisibility
-import info.nightscout.androidaps.interfaces.ActivePlugin
-import info.nightscout.androidaps.interfaces.ProfileFunction
-import info.nightscout.androidaps.logging.AAPSLogger
-import info.nightscout.androidaps.logging.LTag
-import info.nightscout.androidaps.plugins.bus.RxBusWrapper
-import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
-import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
-import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
-import info.nightscout.androidaps.utils.DateUtil
-import info.nightscout.androidaps.utils.DefaultValueHelper
-import info.nightscout.androidaps.utils.FabricPrivacy
-import info.nightscout.androidaps.utils.T
-import info.nightscout.androidaps.utils.buildHelper.BuildHelper
-import info.nightscout.androidaps.utils.rx.AapsSchedulers
-import info.nightscout.androidaps.utils.sharedPreferences.SP
-import io.reactivex.disposables.CompositeDisposable
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import java.util.*
-import javax.inject.Inject
-
-class HistoryBrowseActivity : NoSplashAppCompatActivity() {
-
- @Inject lateinit var injector: HasAndroidInjector
- @Inject lateinit var aapsLogger: AAPSLogger
- @Inject lateinit var aapsSchedulers: AapsSchedulers
- @Inject lateinit var rxBus: RxBusWrapper
- @Inject lateinit var sp: SP
- @Inject lateinit var profileFunction: ProfileFunction
- @Inject lateinit var defaultValueHelper: DefaultValueHelper
- @Inject lateinit var iobCobCalculatorPluginHistory: IobCobCalculatorPluginHistory
- @Inject lateinit var activePlugin: ActivePlugin
- @Inject lateinit var buildHelper: BuildHelper
- @Inject lateinit var fabricPrivacy: FabricPrivacy
- @Inject lateinit var overviewMenus: OverviewMenus
- @Inject lateinit var dateUtil: DateUtil
-
- private val disposable = CompositeDisposable()
-
- private val secondaryGraphs = ArrayList()
- private val secondaryGraphsLabel = ArrayList()
-
- private var axisWidth: Int = 0
- private var rangeToDisplay = 24 // for graph
- private var start: Long = 0
-
- private val graphLock = Object()
-
- private var eventCustomCalculationFinished = EventCustomCalculationFinished()
-
- private lateinit var binding: ActivityHistorybrowseBinding
- private var destroyed = false
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityHistorybrowseBinding.inflate(layoutInflater)
- setContentView(binding.root)
-
- binding.left.setOnClickListener {
- start -= T.hours(rangeToDisplay.toLong()).msecs()
- runCalculation("onClickLeft")
- }
- binding.right.setOnClickListener {
- start += T.hours(rangeToDisplay.toLong()).msecs()
- runCalculation("onClickRight")
- }
- binding.end.setOnClickListener {
- val calendar = Calendar.getInstance()
- calendar.timeInMillis = System.currentTimeMillis()
- calendar[Calendar.MILLISECOND] = 0
- calendar[Calendar.SECOND] = 0
- calendar[Calendar.MINUTE] = 0
- calendar[Calendar.HOUR_OF_DAY] = 0
- start = calendar.timeInMillis
- runCalculation("onClickEnd")
- }
- binding.zoom.setOnClickListener {
- rangeToDisplay += 6
- rangeToDisplay = if (rangeToDisplay > 24) 6 else rangeToDisplay
- updateGUI("rangeChange", false)
- }
- binding.zoom.setOnLongClickListener {
- val calendar = Calendar.getInstance()
- calendar.timeInMillis = start
- calendar[Calendar.MILLISECOND] = 0
- calendar[Calendar.SECOND] = 0
- calendar[Calendar.MINUTE] = 0
- calendar[Calendar.HOUR_OF_DAY] = 0
- start = calendar.timeInMillis
- runCalculation("onLongClickZoom")
- true
- }
-
- // create an OnDateSetListener
- val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
- val cal = Calendar.getInstance()
- cal.timeInMillis = start
- cal[Calendar.YEAR] = year
- cal[Calendar.MONTH] = monthOfYear
- cal[Calendar.DAY_OF_MONTH] = dayOfMonth
- cal[Calendar.MILLISECOND] = 0
- cal[Calendar.SECOND] = 0
- cal[Calendar.MINUTE] = 0
- cal[Calendar.HOUR_OF_DAY] = 0
- start = cal.timeInMillis
- binding.date.text = dateUtil.dateAndTimeString(start)
- runCalculation("onClickDate")
- }
-
- binding.date.setOnClickListener {
- val cal = Calendar.getInstance()
- cal.timeInMillis = start
- DatePickerDialog(this, dateSetListener,
- cal.get(Calendar.YEAR),
- cal.get(Calendar.MONTH),
- cal.get(Calendar.DAY_OF_MONTH)
- ).show()
- }
-
- val dm = DisplayMetrics()
- windowManager?.defaultDisplay?.getMetrics(dm)
-
- 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 = resourceHelper.gc(R.color.graphgrid)
- binding.bggraph.gridLabelRenderer?.reloadStyles()
- binding.bggraph.gridLabelRenderer?.labelVerticalWidth = axisWidth
-
- overviewMenus.setupChartMenu(binding.chartMenuButton)
- prepareGraphsIfNeeded(overviewMenus.setting.size)
- savedInstanceState?.let { bundle ->
- rangeToDisplay = bundle.getInt("rangeToDisplay", 0)
- start = bundle.getLong("start", 0)
- }
-
- }
-
- public override fun onPause() {
- super.onPause()
- disposable.clear()
- iobCobCalculatorPluginHistory.stopCalculation("onPause")
- }
-
- @Synchronized
- override fun onDestroy() {
- destroyed = true
- super.onDestroy()
- }
-
- public override fun onResume() {
- super.onResume()
- disposable.add(rxBus
- .toObservable(EventAutosensCalculationFinished::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({
- // catch only events from iobCobCalculatorPluginHistory
- if (it.cause is EventCustomCalculationFinished) {
- updateGUI("EventAutosensCalculationFinished", bgOnly = false)
- }
- }, fabricPrivacy::logException)
- )
- disposable.add(rxBus
- .toObservable(EventIobCalculationProgress::class.java)
- .observeOn(aapsSchedulers.main)
- .subscribe({ binding.overviewIobcalculationprogess.text = it.progress }, fabricPrivacy::logException)
- )
- disposable.add(rxBus
- .toObservable(EventRefreshOverview::class.java)
- .observeOn(aapsSchedulers.main)
- .subscribe({
- if (it.now) {
- updateGUI("EventRefreshOverview", bgOnly = false)
- }
- }, fabricPrivacy::logException)
- )
- if (start == 0L) {
- // set start of current day
- val calendar = Calendar.getInstance()
- calendar.timeInMillis = System.currentTimeMillis()
- calendar[Calendar.MILLISECOND] = 0
- calendar[Calendar.SECOND] = 0
- calendar[Calendar.MINUTE] = 0
- calendar[Calendar.HOUR_OF_DAY] = 0
- start = calendar.timeInMillis
- runCalculation("onResume")
- } else {
- updateGUI("onResume", bgOnly = false)
- }
- }
-
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- outState.putInt("rangeToDisplay", rangeToDisplay)
- outState.putLong("start", start)
-
- }
-
- private fun prepareGraphsIfNeeded(numOfGraphs: Int) {
- synchronized(graphLock) {
- if (numOfGraphs != secondaryGraphs.size - 1) {
- //aapsLogger.debug("New secondary graph count ${numOfGraphs-1}")
- // rebuild needed
- secondaryGraphs.clear()
- secondaryGraphsLabel.clear()
- binding.iobGraph.removeAllViews()
- for (i in 1 until numOfGraphs) {
- val relativeLayout = RelativeLayout(this)
- relativeLayout.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
-
- val graph = GraphView(this)
- graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, resourceHelper.dpToPx(15), 0, resourceHelper.dpToPx(10)) }
- graph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
- graph.gridLabelRenderer?.reloadStyles()
- graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
- graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
- graph.gridLabelRenderer?.numVerticalLabels = 3
- graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray
- relativeLayout.addView(graph)
-
- val label = TextView(this)
- val layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(resourceHelper.dpToPx(30), resourceHelper.dpToPx(25), 0, 0) }
- layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP)
- layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
- label.layoutParams = layoutParams
- relativeLayout.addView(label)
- secondaryGraphsLabel.add(label)
-
- binding.iobGraph.addView(relativeLayout)
- secondaryGraphs.add(graph)
- }
- }
- }
- }
-
- private fun runCalculation(from: String) {
- lifecycleScope.launch(Dispatchers.Default) {
- val end = start + T.hours(rangeToDisplay.toLong()).msecs()
- iobCobCalculatorPluginHistory.stopCalculation(from)
- iobCobCalculatorPluginHistory.clearCache()
- iobCobCalculatorPluginHistory.runCalculation(from, end, bgDataReload = true, limitDataToOldestAvailable = false, cause = eventCustomCalculationFinished)
- }
- }
-
- @Synchronized
- fun updateGUI(from: String, bgOnly: Boolean) {
- val menuChartSettings = overviewMenus.setting
- prepareGraphsIfNeeded(menuChartSettings.size)
- aapsLogger.debug(LTag.UI, "updateGUI from: $from")
- val pump = activePlugin.activePump
- val profile = profileFunction.getProfile()
-
- val lowLine = defaultValueHelper.determineLowLine()
- val highLine = defaultValueHelper.determineHighLine()
-
- lifecycleScope.launch(Dispatchers.Main) {
- binding.noprofile.visibility = (profile == null).toVisibility()
- profile ?: return@launch
-
- if (destroyed) return@launch
- binding.date.text = dateUtil.dateAndTimeString(start)
- binding.zoom.text = rangeToDisplay.toString()
- val graphData = GraphData(injector, binding.bggraph)
- val secondaryGraphsData: ArrayList = ArrayList()
-
- // do preparation in different thread
- withContext(Dispatchers.Default) {
- val fromTime: Long = start + T.secs(100).msecs()
- val toTime: Long = start + T.hours(rangeToDisplay.toLong()).msecs() + T.secs(100).msecs()
- aapsLogger.debug(LTag.UI, "Period: " + dateUtil.dateAndTimeString(fromTime) + " - " + dateUtil.dateAndTimeString(toTime))
- val pointer = System.currentTimeMillis()
-
- // **** In range Area ****
- graphData.addInRangeArea(fromTime, toTime, lowLine, highLine)
-
- // **** BG ****
-// graphData.addBgReadings(fromTime, toTime, highLine, null)
-// if (buildHelper.isDev()) graphData.addBucketedData(fromTime, toTime)
-
- // add target line
-// graphData.addTargetLine(fromTime, toTime, profile, null)
-
- // **** NOW line ****
- graphData.addNowLine(pointer)
-
- if (!bgOnly) {
- // Treatments
-// graphData.addTreatments(fromTime, toTime)
- if (menuChartSettings[0][OverviewMenus.CharType.ACT.ordinal])
-// graphData.addActivity(fromTime, toTime, false, 0.8)
-
- // add basal data
- if (pump.pumpDescription.isTempBasalCapable && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal]) {
-// graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2)
- }
- // ------------------ 2nd graph
- synchronized(graphLock) {
- for (g in 0 until secondaryGraphs.size) {
- val secondGraphData = GraphData(injector, secondaryGraphs[g])
- var useIobForScale = false
- var useCobForScale = false
- var useDevForScale = false
- var useRatioForScale = false
- var useDSForScale = false
- var useBGIForScale = false
- var useABSForScale = false
- when {
- menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
- menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
- menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
- menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
- menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] -> useBGIForScale = true
- menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
- menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
- }
-
- val alignIobScale = menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] && menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal]
- val alignDevBgiScale = menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] && menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]
-
-// if (menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(fromTime, toTime, useABSForScale, 1.0)
-// if (menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(fromTime, toTime, useIobForScale, 1.0, menuChartSettings[g + 1][OverviewMenus.CharType.PRE.ordinal], alignIobScale)
-// if (menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, toTime, useCobForScale, if (useCobForScale) 1.0 else 0.5)
-// if (menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1.0, alignDevBgiScale)
-// if (menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1.0)
-// if (menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]) secondGraphData.addMinusBGI(fromTime, toTime, useBGIForScale, if (alignDevBgiScale) 1.0 else 0.8, alignDevBgiScale)
-// if (menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1.0)
-
- // set manual x bounds to have nice steps
- secondGraphData.formatAxis(fromTime, toTime)
- secondGraphData.addNowLine(pointer)
- secondaryGraphsData.add(secondGraphData)
- }
- }
- }
-
- // set manual x bounds to have nice steps
- graphData.setNumVerticalLabels()
- graphData.formatAxis(fromTime, toTime)
- }
- // finally enforce drawing of graphs in UI thread
- graphData.performUpdate()
- if (!bgOnly)
- synchronized(graphLock) {
- for (g in 0 until secondaryGraphs.size) {
- secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1)
- secondaryGraphs[g].visibility = (!bgOnly && (
- menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] ||
- menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] ||
- menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] ||
- menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] ||
- menuChartSettings[g + 1][OverviewMenus.CharType.ACT.ordinal] ||
- menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] ||
- menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal]
- )).toVisibility()
- secondaryGraphsData[g].performUpdate()
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobCalculatorPluginHistory.kt b/app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobCalculatorPluginHistory.kt
deleted file mode 100644
index 1dfc35f70a..0000000000
--- a/app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobCalculatorPluginHistory.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package info.nightscout.androidaps.historyBrowser
-
-import dagger.android.HasAndroidInjector
-import info.nightscout.androidaps.database.AppRepository
-import info.nightscout.androidaps.interfaces.ActivePlugin
-import info.nightscout.androidaps.interfaces.ProfileFunction
-import info.nightscout.androidaps.logging.AAPSLogger
-import info.nightscout.androidaps.plugins.bus.RxBusWrapper
-import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
-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.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.androidaps.utils.sharedPreferences.SP
-import javax.inject.Inject
-import javax.inject.Singleton
-
-@Singleton
-class IobCobCalculatorPluginHistory @Inject constructor(
- injector: HasAndroidInjector,
- aapsLogger: AAPSLogger,
- aapsSchedulers: AapsSchedulers,
- rxBus: RxBusWrapper,
- sp: SP,
- resourceHelper: ResourceHelper,
- profileFunction: ProfileFunction,
- activePlugin: ActivePlugin,
- sensitivityOref1Plugin: SensitivityOref1Plugin,
- sensitivityAAPSPlugin: SensitivityAAPSPlugin,
- sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin,
- fabricPrivacy: FabricPrivacy,
- dateUtil: DateUtil,
- repository: AppRepository
-) : IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction,
- activePlugin, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil, repository) {
-
- override fun onStart() { // do not attach to rxbus
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt
index c5049d171d..26a478240a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctionImplementation.kt
@@ -104,7 +104,8 @@ class ProfileFunctionImplementation @Inject constructor(
timeshift = T.hours(timeShiftInHours.toLong()).msecs(),
percentage = percentage,
duration = T.mins(durationInMinutes.toLong()).msecs(),
- insulinConfiguration = activePlugin.activeInsulin.insulinConfiguration)
+ insulinConfiguration = activePlugin.activeInsulin.insulinConfiguration.also { it.insulinEndTime = (pureProfile.dia * 3600 * 1000).toLong() }
+ )
disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps))
.subscribe({ result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") }
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt
index 1e18a5f54f..8ffbd696ee 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt
@@ -28,7 +28,7 @@ import info.nightscout.androidaps.events.EventTherapyEventChange
import info.nightscout.androidaps.extensions.toStringMedium
import info.nightscout.androidaps.extensions.toStringShort
import info.nightscout.androidaps.extensions.toVisibility
-import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
+import info.nightscout.androidaps.activities.HistoryBrowseActivity
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Config
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt
index 5f1e910af8..5f1844315f 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt
@@ -561,9 +561,9 @@ class DataSyncSelectorImplementation @Inject constructor(
val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0)
val lastChange = sp.getLong(R.string.key_local_profile_last_change, 0)
if (lastChange == 0L) return
- localProfilePlugin.createProfileStore()
- val profileJson = localProfilePlugin.profile?.data ?: return
- if (lastChange > lastSync)
+ if (lastChange > lastSync) {
+ val profileJson = localProfilePlugin.profile?.data ?: return
nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
+ }
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt
index 8c73fd908f..b7f1d1540c 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt
@@ -34,7 +34,7 @@ class NSClientMbgWorker(
var ret = Result.success()
val acceptNSData = sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT
- if (!acceptNSData) return ret
+ if (!acceptNSData) return Result.success(workDataOf("Result" to "Sync not enabled"))
val mbgArray = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt
index 1346374246..4beb99759a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt
@@ -1,46 +1,64 @@
package info.nightscout.androidaps.plugins.general.overview
+import android.graphics.DashPathEffect
+import android.graphics.Paint
import com.jjoe64.graphview.series.BarGraphSeries
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.data.IobTotal
+import info.nightscout.androidaps.database.AppRepository
+import info.nightscout.androidaps.database.ValueWrapper
+import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.ExtendedBolus
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TemporaryBasal
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.extensions.convertedToPercent
+import info.nightscout.androidaps.extensions.target
import info.nightscout.androidaps.extensions.toStringFull
import info.nightscout.androidaps.extensions.toStringShort
import info.nightscout.androidaps.extensions.valueToUnits
-import info.nightscout.androidaps.interfaces.ActivePlugin
-import info.nightscout.androidaps.interfaces.Profile
-import info.nightscout.androidaps.interfaces.ProfileFunction
-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.interfaces.*
+import info.nightscout.androidaps.logging.AAPSLogger
+import info.nightscout.androidaps.logging.LTag
+import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
+import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
+import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
+import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
+import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
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.DefaultValueHelper
-import info.nightscout.androidaps.utils.T
+import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.util.*
import javax.inject.Inject
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
class OverviewData @Inject constructor(
+ private val injector: HasAndroidInjector,
+ private val aapsLogger: AAPSLogger,
private val resourceHelper: ResourceHelper,
private val dateUtil: DateUtil,
private val sp: SP,
private val activePlugin: ActivePlugin,
private val defaultValueHelper: DefaultValueHelper,
- private val profileFunction: ProfileFunction
+ private val profileFunction: ProfileFunction,
+ private val config: Config,
+ private val loopPlugin: LoopPlugin,
+ private val nsDeviceStatus: NSDeviceStatus,
+ private val repository: AppRepository,
+ private val overviewMenus: OverviewMenus,
+ private val iobCobCalculator: IobCobCalculator,
+ private val translator: Translator
) {
enum class Property {
@@ -84,7 +102,7 @@ class OverviewData @Inject constructor(
var profileName: String? = null
var profileNameWithRemainingTime: String? = null
- val profileBackgroudColor: Int
+ val profileBackgroundColor: Int
get() =
profile?.let { profile ->
if (profile.percentage != 100 || profile.timeshift != 0) resourceHelper.gc(R.color.ribbonWarning)
@@ -211,7 +229,7 @@ class OverviewData @Inject constructor(
* TEMP TARGET
*/
- var temporarytarget: TemporaryTarget? = null
+ var temporaryTarget: TemporaryTarget? = null
/*
* SENSITIVITY
@@ -278,4 +296,515 @@ class OverviewData @Inject constructor(
var dsMaxSeries: LineGraphSeries = LineGraphSeries()
var dsMinSeries: LineGraphSeries = 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 = 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, resourceHelper))
+ }
+ 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) loopPlugin.lastRun?.constraintsProcessed else nsDeviceStatus.getAPSResult(injector)
+ val predictionsAvailable = if (config.APS) loopPlugin.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 = java.util.ArrayList()
+ val predictions: MutableList? = apsResult?.predictions
+ ?.map { bg -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper) }
+ ?.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 = java.util.ArrayList()
+ for (inMemoryGlucoseValue in bucketedData) {
+ if (inMemoryGlucoseValue.timestamp < fromTime || inMemoryGlucoseValue.timestamp > toTime) continue
+ bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, profileFunction, resourceHelper))
+ }
+ 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 = java.util.ArrayList()
+ val tempBasalArray: MutableList = java.util.ArrayList()
+ val basalLineArray: MutableList = java.util.ArrayList()
+ val absoluteBasalLineArray: MutableList = 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 = resourceHelper.gc(R.color.basebasal)
+ it.thickness = 0
+ }
+ tempBasalGraphSeries = LineGraphSeries(Array(tempBasalArray.size) { i -> tempBasalArray[i] }).also {
+ it.isDrawBackground = true
+ it.backgroundColor = resourceHelper.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 = resourceHelper.getDisplayMetrics().scaledDensity * 2
+ paint.pathEffect = DashPathEffect(floatArrayOf(2f, 4f), 0f)
+ paint.color = resourceHelper.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 = resourceHelper.getDisplayMetrics().scaledDensity * 2
+ absolutePaint.color = resourceHelper.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 = profile ?: return
+ val units = profileFunction.getUnits()
+ var toTime = toTime
+ val targetsSeriesArray: MutableList = java.util.ArrayList()
+ var lastTarget = -1.0
+ loopPlugin.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 = resourceHelper.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 = java.util.ArrayList()
+ repository.getBolusesIncludingInvalidFromTimeToTime(fromTime, endTime, true).blockingGet()
+ .map { BolusDataPoint(it, resourceHelper, activePlugin, defaultValueHelper) }
+ .filter { it.data.type != Bolus.Type.SMB || it.data.isValid }
+ .forEach {
+ it.y = getNearestBg(it.x.toLong())
+ filteredTreatments.add(it)
+ }
+ repository.getCarbsIncludingInvalidFromTimeToTimeExpanded(fromTime, endTime, true).blockingGet()
+ .map { CarbsDataPoint(it, resourceHelper) }
+ .forEach {
+ it.y = getNearestBg(it.x.toLong())
+ filteredTreatments.add(it)
+ }
+
+ // ProfileSwitch
+ repository.getEffectiveProfileSwitchDataFromTimeToTime(fromTime, endTime, true).blockingGet()
+ .map { EffectiveProfileSwitchDataPoint(it) }
+ .forEach(filteredTreatments::add)
+
+ // Extended bolus
+ if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
+ repository.getExtendedBolusDataFromTimeToTime(fromTime, endTime, true).blockingGet()
+ .map { ExtendedBolusDataPoint(it) }
+ .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, resourceHelper, 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 = java.util.ArrayList()
+ val absIobArray: MutableList = java.util.ArrayList()
+ maxIobValueFound = Double.MIN_VALUE
+ var lastIob = 0.0
+ var absLastIob = 0.0
+ var time = fromTime
+
+ val minFailOverActiveList: MutableList = java.util.ArrayList()
+ val cobArray: MutableList = java.util.ArrayList()
+ maxCobValueFound = Double.MIN_VALUE
+ var lastCob = 0
+
+ val actArrayHist: MutableList = java.util.ArrayList()
+ val actArrayPrediction: MutableList = java.util.ArrayList()
+ val now = dateUtil.now().toDouble()
+ maxIAValue = 0.0
+
+ val bgiArrayHist: MutableList = java.util.ArrayList()
+ val bgiArrayPrediction: MutableList = java.util.ArrayList()
+ maxBGIValue = Double.MIN_VALUE
+
+ val devArray: MutableList = java.util.ArrayList()
+ maxDevValueFound = Double.MIN_VALUE
+
+ val ratioArray: MutableList = 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 = java.util.ArrayList()
+ val dsMinArray: MutableList = 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.failoverToMinAbsorbtionRate) {
+ autosensData.setScale(cobScale)
+ autosensData.setChartTime(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 = resourceHelper.gc(R.color.deviationblack) // "="
+ if (autosensData.type == "" || autosensData.type == "non-meal") {
+ if (autosensData.pastSensitivity == "C") color = resourceHelper.gc(R.color.deviationgrey)
+ if (autosensData.pastSensitivity == "+") color = resourceHelper.gc(R.color.deviationgreen)
+ if (autosensData.pastSensitivity == "-") color = resourceHelper.gc(R.color.deviationred)
+ } else if (autosensData.type == "uam") {
+ color = resourceHelper.gc(R.color.uam)
+ } else if (autosensData.type == "csf") {
+ color = resourceHelper.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 resourceHelper.gc(R.color.iob) //50%
+ it.color = resourceHelper.gc(R.color.iob)
+ it.thickness = 3
+ }
+ absIobSeries = FixedLineGraphSeries(Array(absIobArray.size) { i -> absIobArray[i] }).also {
+ it.isDrawBackground = true
+ it.backgroundColor = -0x7f000001 and resourceHelper.gc(R.color.iob) //50%
+ it.color = resourceHelper.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 = 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(resourceHelper.gc(R.color.iobPredAS)))
+ maxIobValueFound = max(maxIobValueFound, abs(i.iob))
+ }
+ iobPredictions1Series = PointsWithLabelGraphSeries(Array(iobPrediction.size) { i -> iobPrediction[i] })
+ val iobPrediction2: MutableList = 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(resourceHelper.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(lastAutosensResult.ratio) + ": " + iobCobCalculator.iobArrayToString(iobPredictionArray))
+ 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 resourceHelper.gc(R.color.cob) //50%
+ it.color = resourceHelper.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 = resourceHelper.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 = resourceHelper.gc(R.color.activity)
+ })
+ }
+
+ // BGI
+ minusBgiSeries = FixedLineGraphSeries(Array(bgiArrayHist.size) { i -> bgiArrayHist[i] }).also {
+ it.isDrawBackground = false
+ it.color = resourceHelper.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 = resourceHelper.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 = resourceHelper.gc(R.color.ratio)
+ it.thickness = 3
+ }
+
+ // DEV SLOPE
+ dsMaxSeries = LineGraphSeries(Array(dsMaxArray.size) { i -> dsMaxArray[i] }).also {
+ it.color = resourceHelper.gc(R.color.devslopepos)
+ it.thickness = 3
+ }
+ dsMinSeries = LineGraphSeries(Array(dsMinArray.size) { i -> dsMinArray[i] }).also {
+ it.color = resourceHelper.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 List.filterTimeframe(fromTime: Long, endTime: Long): List =
+ filter { it.x + it.duration >= fromTime && it.x <= endTime }
+
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt
index 9217164710..9f02c3297a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt
@@ -57,7 +57,6 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProv
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.source.DexcomPlugin
import info.nightscout.androidaps.plugins.source.XdripPlugin
-import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.CommandQueue
import info.nightscout.androidaps.skins.SkinProvider
import info.nightscout.androidaps.utils.*
@@ -92,7 +91,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var nsDeviceStatus: NSDeviceStatus
@Inject lateinit var loopPlugin: LoopPlugin
@Inject lateinit var activePlugin: ActivePlugin
- @Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var dexcomPlugin: DexcomPlugin
@Inject lateinit var dexcomMediator: DexcomPlugin.DexcomMediator
@@ -108,7 +106,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var trendCalculator: TrendCalculator
@Inject lateinit var config: Config
@Inject lateinit var dateUtil: DateUtil
- @Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var repository: AppRepository
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
@@ -623,7 +620,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.avgDelta.text = Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units)
} else {
- binding.infoLayout.deltaLarge.text = "Δ " + resourceHelper.gs(R.string.notavailable)
+ binding.infoLayout.deltaLarge.text = ""
binding.infoLayout.delta.text = "Δ " + resourceHelper.gs(R.string.notavailable)
binding.infoLayout.avgDelta.text = ""
binding.infoLayout.longAvgDelta.text = ""
@@ -640,7 +637,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
OverviewData.Property.PROFILE -> {
binding.loopPumpStatusLayout.activeProfile.text = overviewData.profileNameWithRemainingTime
?: ""
- binding.loopPumpStatusLayout.activeProfile.setBackgroundColor(overviewData.profileBackgroudColor)
+ binding.loopPumpStatusLayout.activeProfile.setBackgroundColor(overviewData.profileBackgroundColor)
binding.loopPumpStatusLayout.activeProfile.setTextColor(overviewData.profileTextColor)
}
@@ -705,7 +702,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
OverviewData.Property.TEMPORARY_TARGET -> {
// temp target
- val tempTarget = overviewData.temporarytarget
+ val tempTarget = overviewData.temporaryTarget
if (tempTarget != null) {
binding.loopPumpStatusLayout.tempTarget.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning))
binding.loopPumpStatusLayout.tempTarget.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning))
@@ -730,7 +727,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}
OverviewData.Property.GRAPH -> {
- val graphData = GraphData(injector, binding.graphsLayout.bgGraph)
+ val graphData = GraphData(injector, binding.graphsLayout.bgGraph, overviewData)
val menuChartSettings = overviewMenus.setting
graphData.addInRangeArea(overviewData.fromTime, overviewData.endTime, defaultValueHelper.determineLowLine(), defaultValueHelper.determineHighLine())
graphData.addBgReadings(menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
@@ -755,7 +752,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val now = System.currentTimeMillis()
for (g in 0 until min(secondaryGraphs.size, menuChartSettings.size + 1)) {
- val secondGraphData = GraphData(injector, secondaryGraphs[g])
+ val secondGraphData = GraphData(injector, secondaryGraphs[g], overviewData)
var useABSForScale = false
var useIobForScale = false
var useCobForScale = false
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt
index 39c51ac5a2..fe5a30dbb4 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt
@@ -1,85 +1,68 @@
package info.nightscout.androidaps.plugins.general.overview
-import android.graphics.DashPathEffect
-import android.graphics.Paint
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
-import com.jjoe64.graphview.series.BarGraphSeries
-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.data.IobTotal
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
-import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.extensions.*
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.events.EventLoopInvoked
-import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
-import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
-import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
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.EventUpdateOverview
-import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
+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.notifications.NotificationStore
-import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
-import info.nightscout.androidaps.utils.*
+import info.nightscout.androidaps.utils.DateUtil
+import info.nightscout.androidaps.utils.FabricPrivacy
+import info.nightscout.androidaps.utils.Translator
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import org.json.JSONObject
-import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
-import kotlin.math.abs
-import kotlin.math.ceil
-import kotlin.math.max
-import kotlin.math.min
@Singleton
class OverviewPlugin @Inject constructor(
- injector: HasAndroidInjector,
- private val notificationStore: NotificationStore,
- private val fabricPrivacy: FabricPrivacy,
- private val rxBus: RxBusWrapper,
- private val sp: SP,
- aapsLogger: AAPSLogger,
- private val aapsSchedulers: AapsSchedulers,
- resourceHelper: ResourceHelper,
- private val config: Config,
- private val dateUtil: DateUtil,
- private val translator: Translator,
+ injector: HasAndroidInjector,
+ private val notificationStore: NotificationStore,
+ private val fabricPrivacy: FabricPrivacy,
+ private val rxBus: RxBusWrapper,
+ private val sp: SP,
+ aapsLogger: AAPSLogger,
+ private val aapsSchedulers: AapsSchedulers,
+ resourceHelper: ResourceHelper,
+ private val config: Config,
+ private val dateUtil: DateUtil,
+ private val translator: Translator,
// private val profiler: Profiler,
- private val profileFunction: ProfileFunction,
- private val iobCobCalculator: IobCobCalculator,
- private val repository: AppRepository,
- private val defaultValueHelper: DefaultValueHelper,
- private val loopPlugin: LoopPlugin,
- private val activePlugin: ActivePlugin,
- private val nsDeviceStatus: NSDeviceStatus,
- private val overviewData: OverviewData,
- private val overviewMenus: OverviewMenus
+ private val profileFunction: ProfileFunction,
+ private val iobCobCalculator: IobCobCalculator,
+ private val repository: AppRepository,
+ private val overviewData: OverviewData,
+ private val overviewMenus: OverviewMenus
) : PluginBase(PluginDescription()
- .mainType(PluginType.GENERAL)
- .fragmentClass(OverviewFragment::class.qualifiedName)
- .alwaysVisible(true)
- .alwaysEnabled(true)
- .pluginIcon(R.drawable.ic_home)
- .pluginName(R.string.overview)
- .shortName(R.string.overview_shortname)
- .preferencesId(R.xml.pref_overview)
- .description(R.string.description_overview),
- aapsLogger, resourceHelper, injector
+ .mainType(PluginType.GENERAL)
+ .fragmentClass(OverviewFragment::class.qualifiedName)
+ .alwaysVisible(true)
+ .alwaysEnabled(true)
+ .pluginIcon(R.drawable.ic_home)
+ .pluginName(R.string.overview)
+ .shortName(R.string.overview_shortname)
+ .preferencesId(R.xml.pref_overview)
+ .description(R.string.description_overview),
+ aapsLogger, resourceHelper, injector
), Overview {
private var disposable: CompositeDisposable = CompositeDisposable()
@@ -95,74 +78,76 @@ class OverviewPlugin @Inject constructor(
notificationStore.createNotificationChannel()
disposable += rxBus
- .toObservable(EventNewNotification::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ n ->
- if (notificationStore.add(n.notification))
- rxBus.send(EventRefreshOverview("EventNewNotification"))
- }, fabricPrivacy::logException)
+ .toObservable(EventNewNotification::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ n ->
+ if (notificationStore.add(n.notification))
+ rxBus.send(EventRefreshOverview("EventNewNotification"))
+ }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventDismissNotification::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ n ->
- if (notificationStore.remove(n.id))
- rxBus.send(EventRefreshOverview("EventDismissNotification"))
- }, fabricPrivacy::logException)
+ .toObservable(EventDismissNotification::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ n ->
+ if (notificationStore.remove(n.id))
+ rxBus.send(EventRefreshOverview("EventDismissNotification"))
+ }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventIobCalculationProgress::class.java)
- .observeOn(aapsSchedulers.main)
- .subscribe({ overviewData.calcProgress = it.progress; overviewBus.send(EventUpdateOverview("EventIobCalculationProgress", OverviewData.Property.CALC_PROGRESS)) }, fabricPrivacy::logException)
+ .toObservable(EventIobCalculationProgress::class.java)
+ .observeOn(aapsSchedulers.main)
+ .subscribe({ overviewData.calcProgress = it.progress; overviewBus.send(EventUpdateOverview("EventIobCalculationProgress", OverviewData.Property.CALC_PROGRESS)) }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventTempBasalChange::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ loadTemporaryBasal("EventTempBasalChange") }, fabricPrivacy::logException)
+ .toObservable(EventTempBasalChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ loadTemporaryBasal("EventTempBasalChange") }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventExtendedBolusChange::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ loadExtendedBolus("EventExtendedBolusChange") }, fabricPrivacy::logException)
+ .toObservable(EventExtendedBolusChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ loadExtendedBolus("EventExtendedBolusChange") }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventNewBG::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ loadBg("EventNewBG") }, fabricPrivacy::logException)
+ .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)
+ .toObservable(EventTempTargetChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ loadTemporaryTarget("EventTempTargetChange") }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventTreatmentChange::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({
- loadIobCobResults("EventTreatmentChange")
- prepareTreatmentsData("EventTreatmentChange")
- overviewBus.send(EventUpdateOverview("EventTreatmentChange", OverviewData.Property.GRAPH))
- }, fabricPrivacy::logException)
+ .toObservable(EventTreatmentChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({
+ loadIobCobResults("EventTreatmentChange")
+ overviewData.prepareTreatmentsData("EventTreatmentChange")
+ overviewBus.send(EventUpdateOverview("EventTreatmentChange", OverviewData.Property.GRAPH))
+ }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventTherapyEventChange::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({
- prepareTreatmentsData("EventTherapyEventChange")
- overviewBus.send(EventUpdateOverview("EventTherapyEventChange", OverviewData.Property.GRAPH))
- }, fabricPrivacy::logException)
+ .toObservable(EventTherapyEventChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({
+ overviewData.prepareTreatmentsData("EventTherapyEventChange")
+ overviewBus.send(EventUpdateOverview("EventTherapyEventChange", OverviewData.Property.GRAPH))
+ }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventBucketedDataCreated::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({
- prepareBucketedData("EventBucketedDataCreated")
- prepareBgData("EventBucketedDataCreated")
- overviewBus.send(EventUpdateOverview("EventBucketedDataCreated", OverviewData.Property.GRAPH))
- }, fabricPrivacy::logException)
+ .toObservable(EventBucketedDataCreated::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({
+ overviewData.prepareBucketedData("EventBucketedDataCreated")
+ overviewData.prepareBgData("EventBucketedDataCreated")
+ overviewBus.send(EventUpdateOverview("EventBucketedDataCreated", OverviewData.Property.GRAPH))
+ }, fabricPrivacy::logException)
disposable += rxBus
- .toObservable(EventLoopInvoked::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ preparePredictions("EventLoopInvoked") }, fabricPrivacy::logException)
+ .toObservable(EventLoopInvoked::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ overviewData.preparePredictions("EventLoopInvoked") }, fabricPrivacy::logException)
disposable.add(rxBus
- .toObservable(EventProfileSwitchChanged::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ loadProfile("EventProfileSwitchChanged") }, fabricPrivacy::logException))
+ .toObservable(EventProfileSwitchChanged::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ loadProfile("EventProfileSwitchChanged") }, fabricPrivacy::logException))
disposable.add(rxBus
- .toObservable(EventAutosensCalculationFinished::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ refreshLoop("EventAutosensCalculationFinished") }, fabricPrivacy::logException))
+ .toObservable(EventAutosensCalculationFinished::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({
+ if (it.cause !is EventCustomCalculationFinished) refreshLoop("EventAutosensCalculationFinished")
+ }, fabricPrivacy::logException))
Thread { loadAll("onResume") }.start()
}
@@ -187,59 +172,60 @@ class OverviewPlugin @Inject constructor(
}
override fun configuration(): JSONObject =
- JSONObject()
- .putString(R.string.key_quickwizard, sp, resourceHelper)
- .putInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
- .putDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
- .putInt(R.string.key_activity_duration, sp, resourceHelper)
- .putDouble(R.string.key_activity_target, sp, resourceHelper)
- .putInt(R.string.key_hypo_duration, sp, resourceHelper)
- .putDouble(R.string.key_hypo_target, sp, resourceHelper)
- .putDouble(R.string.key_low_mark, sp, resourceHelper)
- .putDouble(R.string.key_high_mark, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_cage_warning, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_cage_critical, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_iage_warning, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_iage_critical, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_sage_warning, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_sage_critical, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_sbat_warning, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_sbat_critical, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_bage_warning, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_bage_critical, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_res_warning, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_res_critical, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_bat_warning, sp, resourceHelper)
- .putDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
+ JSONObject()
+ .putString(R.string.key_quickwizard, sp, resourceHelper)
+ .putInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
+ .putDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
+ .putInt(R.string.key_activity_duration, sp, resourceHelper)
+ .putDouble(R.string.key_activity_target, sp, resourceHelper)
+ .putInt(R.string.key_hypo_duration, sp, resourceHelper)
+ .putDouble(R.string.key_hypo_target, sp, resourceHelper)
+ .putDouble(R.string.key_low_mark, sp, resourceHelper)
+ .putDouble(R.string.key_high_mark, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_cage_warning, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_cage_critical, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_iage_warning, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_iage_critical, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_sage_warning, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_sage_critical, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_sbat_warning, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_sbat_critical, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_bage_warning, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_bage_critical, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_res_warning, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_res_critical, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_bat_warning, sp, resourceHelper)
+ .putDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
override fun applyConfiguration(configuration: JSONObject) {
configuration
- .storeString(R.string.key_quickwizard, sp, resourceHelper)
- .storeInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
- .storeDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
- .storeInt(R.string.key_activity_duration, sp, resourceHelper)
- .storeDouble(R.string.key_activity_target, sp, resourceHelper)
- .storeInt(R.string.key_hypo_duration, sp, resourceHelper)
- .storeDouble(R.string.key_hypo_target, sp, resourceHelper)
- .storeDouble(R.string.key_low_mark, sp, resourceHelper)
- .storeDouble(R.string.key_high_mark, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_cage_warning, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_cage_critical, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_iage_warning, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_iage_critical, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_sage_warning, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_sage_critical, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_sbat_warning, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_sbat_critical, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_bage_warning, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_bage_critical, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_res_warning, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_res_critical, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_bat_warning, sp, resourceHelper)
- .storeDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
+ .storeString(R.string.key_quickwizard, sp, resourceHelper)
+ .storeInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
+ .storeDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
+ .storeInt(R.string.key_activity_duration, sp, resourceHelper)
+ .storeDouble(R.string.key_activity_target, sp, resourceHelper)
+ .storeInt(R.string.key_hypo_duration, sp, resourceHelper)
+ .storeDouble(R.string.key_hypo_target, sp, resourceHelper)
+ .storeDouble(R.string.key_low_mark, sp, resourceHelper)
+ .storeDouble(R.string.key_high_mark, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_cage_warning, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_cage_critical, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_iage_warning, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_iage_critical, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_sage_warning, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_sage_critical, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_sbat_warning, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_sbat_critical, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_bage_warning, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_bage_critical, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_res_warning, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_res_critical, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_bat_warning, sp, resourceHelper)
+ .storeDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
}
- @Volatile var runningRefresh = false
+ @Volatile
+ var runningRefresh = false
override fun refreshLoop(from: String) {
if (runningRefresh) return
runningRefresh = true
@@ -252,11 +238,11 @@ class OverviewPlugin @Inject constructor(
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_TARGET))
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.SENSITIVITY))
loadAsData(from)
- preparePredictions(from)
- prepareBasalData(from)
- prepareTemporaryTargetData(from)
- prepareTreatmentsData(from)
- prepareIobAutosensData(from)
+ overviewData.preparePredictions(from)
+ overviewData.prepareBasalData(from)
+ overviewData.prepareTemporaryTargetData(from)
+ overviewData.prepareTreatmentsData(from)
+ overviewData.prepareIobAutosensData(from)
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.GRAPH))
aapsLogger.debug(LTag.UI, "refreshLoop finished")
runningRefresh = false
@@ -271,9 +257,9 @@ class OverviewPlugin @Inject constructor(
loadTemporaryTarget(from)
loadIobCobResults(from)
loadAsData(from)
- prepareBasalData(from)
- prepareTemporaryTargetData(from)
- prepareTreatmentsData(from)
+ overviewData.prepareBasalData(from)
+ overviewData.prepareTemporaryTargetData(from)
+ overviewData.prepareTreatmentsData(from)
// prepareIobAutosensData(from)
// preparePredictions(from)
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.GRAPH))
@@ -299,8 +285,8 @@ class OverviewPlugin @Inject constructor(
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
+ if (tempTarget is ValueWrapper.Existing) overviewData.temporaryTarget = tempTarget.value
+ else overviewData.temporaryTarget = null
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_TARGET))
}
@@ -326,514 +312,4 @@ class OverviewPlugin @Inject constructor(
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.IOB_COB))
}
- @Synchronized
- @Suppress("SameParameterValue", "UNUSED_PARAMETER")
- private fun prepareBgData(from: String) {
-// val start = dateUtil.now()
- var maxBgValue = Double.MIN_VALUE
- overviewData.bgReadingsArray = repository.compatGetBgReadingsDataFromTime(overviewData.fromTime, overviewData.toTime, false).blockingGet()
- val bgListArray: MutableList = ArrayList()
- for (bg in overviewData.bgReadingsArray) {
- if (bg.timestamp < overviewData.fromTime || bg.timestamp > overviewData.toTime) continue
- if (bg.value > maxBgValue) maxBgValue = bg.value
- bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper))
- }
- overviewData.bgReadingGraphSeries = PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] })
- overviewData.maxBgValue = Profile.fromMgdlToUnits(maxBgValue, profileFunction.getUnits())
- if (defaultValueHelper.determineHighLine() > maxBgValue) overviewData.maxBgValue = defaultValueHelper.determineHighLine()
- overviewData.maxBgValue = addUpperChartMargin(overviewData.maxBgValue)
-// profiler.log(LTag.UI, "prepareBgData() $from", start)
- }
-
- @Suppress("UNUSED_PARAMETER")
- @Synchronized
- private fun preparePredictions(from: String) {
-// val start = dateUtil.now()
- val apsResult = if (config.APS) loopPlugin.lastRun?.constraintsProcessed else nsDeviceStatus.getAPSResult(injector)
- val predictionsAvailable = if (config.APS) loopPlugin.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 = overviewData.rangeToDisplay - predictionHours
- overviewData.toTime = calendar.timeInMillis + 100000 // little bit more to avoid wrong rounding - GraphView specific
- overviewData.fromTime = overviewData.toTime - T.hours(hoursToFetch.toLong()).msecs()
- overviewData.endTime = overviewData.toTime + T.hours(predictionHours.toLong()).msecs()
- } else {
- overviewData.toTime = calendar.timeInMillis + 100000 // little bit more to avoid wrong rounding - GraphView specific
- overviewData.fromTime = overviewData.toTime - T.hours(overviewData.rangeToDisplay.toLong()).msecs()
- overviewData.endTime = overviewData.toTime
- }
-
- val bgListArray: MutableList = ArrayList()
- val predictions: MutableList? = apsResult?.predictions
- ?.map { bg -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper) }
- ?.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)
- }
- overviewData.predictionsGraphSeries = PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] })
-// profiler.log(LTag.UI, "preparePredictions() $from", start)
- }
-
- @Synchronized
- @Suppress("SameParameterValue", "UNUSED_PARAMETER")
- private 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 = ArrayList()
- for (inMemoryGlucoseValue in bucketedData) {
- if (inMemoryGlucoseValue.timestamp < overviewData.fromTime || inMemoryGlucoseValue.timestamp > overviewData.toTime) continue
- bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, profileFunction, resourceHelper))
- }
- overviewData.bucketedGraphSeries = PointsWithLabelGraphSeries(Array(bucketedListArray.size) { i -> bucketedListArray[i] })
-// profiler.log(LTag.UI, "prepareBucketedData() $from", start)
- }
-
- @Suppress("UNUSED_PARAMETER")
- @Synchronized
- private fun prepareBasalData(from: String) {
-// val start = dateUtil.now()
- overviewData.maxBasalValueFound = 0.0
- val baseBasalArray: MutableList = ArrayList()
- val tempBasalArray: MutableList = ArrayList()
- val basalLineArray: MutableList = ArrayList()
- val absoluteBasalLineArray: MutableList = ArrayList()
- var lastLineBasal = 0.0
- var lastAbsoluteLineBasal = -1.0
- var lastBaseBasal = 0.0
- var lastTempBasal = 0.0
- var time = overviewData.fromTime
- while (time < overviewData.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, overviewData.basalScale))
- tempBasalArray.add(ScaledDataPoint(time, tempBasalValue.also { basal = it }, overviewData.basalScale))
- }
- if (lastBaseBasal != 0.0) {
- baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, overviewData.basalScale))
- baseBasalArray.add(ScaledDataPoint(time, 0.0, overviewData.basalScale))
- lastBaseBasal = 0.0
- }
- } else {
- if (baseBasalValue != lastBaseBasal) {
- baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, overviewData.basalScale))
- baseBasalArray.add(ScaledDataPoint(time, baseBasalValue.also { basal = it }, overviewData.basalScale))
- lastBaseBasal = baseBasalValue
- }
- if (lastTempBasal != 0.0) {
- tempBasalArray.add(ScaledDataPoint(time, lastTempBasal, overviewData.basalScale))
- tempBasalArray.add(ScaledDataPoint(time, 0.0, overviewData.basalScale))
- }
- }
- if (baseBasalValue != lastLineBasal) {
- basalLineArray.add(ScaledDataPoint(time, lastLineBasal, overviewData.basalScale))
- basalLineArray.add(ScaledDataPoint(time, baseBasalValue, overviewData.basalScale))
- }
- if (absoluteLineValue != lastAbsoluteLineBasal) {
- absoluteBasalLineArray.add(ScaledDataPoint(time, lastAbsoluteLineBasal, overviewData.basalScale))
- absoluteBasalLineArray.add(ScaledDataPoint(time, basal, overviewData.basalScale))
- }
- lastAbsoluteLineBasal = absoluteLineValue
- lastLineBasal = baseBasalValue
- lastTempBasal = tempBasalValue
- overviewData.maxBasalValueFound = max(overviewData.maxBasalValueFound, max(tempBasalValue, baseBasalValue))
- time += 60 * 1000L
- }
-
- // final points
- basalLineArray.add(ScaledDataPoint(overviewData.toTime, lastLineBasal, overviewData.basalScale))
- baseBasalArray.add(ScaledDataPoint(overviewData.toTime, lastBaseBasal, overviewData.basalScale))
- tempBasalArray.add(ScaledDataPoint(overviewData.toTime, lastTempBasal, overviewData.basalScale))
- absoluteBasalLineArray.add(ScaledDataPoint(overviewData.toTime, lastAbsoluteLineBasal, overviewData.basalScale))
-
- // create series
- overviewData.baseBasalGraphSeries = LineGraphSeries(Array(baseBasalArray.size) { i -> baseBasalArray[i] }).also {
- it.isDrawBackground = true
- it.backgroundColor = resourceHelper.gc(R.color.basebasal)
- it.thickness = 0
- }
- overviewData.tempBasalGraphSeries = LineGraphSeries(Array(tempBasalArray.size) { i -> tempBasalArray[i] }).also {
- it.isDrawBackground = true
- it.backgroundColor = resourceHelper.gc(R.color.tempbasal)
- it.thickness = 0
- }
- overviewData.basalLineGraphSeries = LineGraphSeries(Array(basalLineArray.size) { i -> basalLineArray[i] }).also {
- it.setCustomPaint(Paint().also { paint ->
- paint.style = Paint.Style.STROKE
- paint.strokeWidth = resourceHelper.getDisplayMetrics().scaledDensity * 2
- paint.pathEffect = DashPathEffect(floatArrayOf(2f, 4f), 0f)
- paint.color = resourceHelper.gc(R.color.basal)
- })
- }
- overviewData.absoluteBasalGraphSeries = LineGraphSeries(Array(absoluteBasalLineArray.size) { i -> absoluteBasalLineArray[i] }).also {
- it.setCustomPaint(Paint().also { absolutePaint ->
- absolutePaint.style = Paint.Style.STROKE
- absolutePaint.strokeWidth = resourceHelper.getDisplayMetrics().scaledDensity * 2
- absolutePaint.color = resourceHelper.gc(R.color.basal)
- })
- }
-// profiler.log(LTag.UI, "prepareBasalData() $from", start)
- }
-
- @Suppress("UNUSED_PARAMETER")
- @Synchronized
- private fun prepareTemporaryTargetData(from: String) {
-// val start = dateUtil.now()
- val profile = overviewData.profile ?: return
- val units = profileFunction.getUnits()
- var toTime = overviewData.toTime
- val targetsSeriesArray: MutableList = ArrayList()
- var lastTarget = -1.0
- loopPlugin.lastRun?.constraintsProcessed?.let { toTime = max(it.latestPredictionsTime, toTime) }
- var time = overviewData.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
- overviewData.temporaryTargetSeries = LineGraphSeries(Array(targetsSeriesArray.size) { i -> targetsSeriesArray[i] }).also {
- it.isDrawBackground = false
- it.color = resourceHelper.gc(R.color.tempTargetBackground)
- it.thickness = 2
- }
-// profiler.log(LTag.UI, "prepareTemporaryTargetData() $from", start)
- }
-
- @Suppress("UNUSED_PARAMETER")
- @Synchronized
- private fun prepareTreatmentsData(from: String) {
-// val start = dateUtil.now()
- overviewData.maxTreatmentsValue = 0.0
- val filteredTreatments: MutableList = ArrayList()
- repository.getBolusesIncludingInvalidFromTimeToTime(overviewData.fromTime, overviewData.endTime, true).blockingGet()
- .map { BolusDataPoint(it, resourceHelper, activePlugin, defaultValueHelper) }
- .filter { it.data.type != Bolus.Type.SMB || it.data.isValid }
- .forEach {
- it.y = getNearestBg(it.x.toLong())
- filteredTreatments.add(it)
- }
- repository.getCarbsIncludingInvalidFromTimeToTimeExpanded(overviewData.fromTime, overviewData.endTime, true).blockingGet()
- .map { CarbsDataPoint(it, resourceHelper) }
- .forEach {
- it.y = getNearestBg(it.x.toLong())
- filteredTreatments.add(it)
- }
-
- // ProfileSwitch
- repository.getEffectiveProfileSwitchDataFromTimeToTime(overviewData.fromTime, overviewData.endTime, true).blockingGet()
- .map { EffectiveProfileSwitchDataPoint(it) }
- .forEach(filteredTreatments::add)
-
- // Extended bolus
- if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
- repository.getExtendedBolusDataFromTimeToTime(overviewData.fromTime, overviewData.endTime, true).blockingGet()
- .map { ExtendedBolusDataPoint(it) }
- .filter { it.duration != 0L }
- .forEach {
- it.y = getNearestBg(it.x.toLong())
- filteredTreatments.add(it)
- }
- }
-
- // Careportal
- repository.compatGetTherapyEventDataFromToTime(overviewData.fromTime - T.hours(6).msecs(), overviewData.endTime).blockingGet()
- .map { TherapyEventDataPoint(it, resourceHelper, profileFunction, translator) }
- .filterTimeframe(overviewData.fromTime, overviewData.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 { overviewData.maxTreatmentsValue = maxOf(overviewData.maxTreatmentsValue, it) }
-
- overviewData.treatmentsSeries = PointsWithLabelGraphSeries(filteredTreatments.toTypedArray())
-// profiler.log(LTag.UI, "prepareTreatmentsData() $from", start)
- }
-
- @Suppress("UNUSED_PARAMETER")
- @Synchronized
- private fun prepareIobAutosensData(from: String) {
-// val start = dateUtil.now()
- val iobArray: MutableList = ArrayList()
- val absIobArray: MutableList = ArrayList()
- overviewData.maxIobValueFound = Double.MIN_VALUE
- var lastIob = 0.0
- var absLastIob = 0.0
- var time = overviewData.fromTime
-
- val minFailOverActiveList: MutableList = ArrayList()
- val cobArray: MutableList = ArrayList()
- overviewData.maxCobValueFound = Double.MIN_VALUE
- var lastCob = 0
-
- val actArrayHist: MutableList = ArrayList()
- val actArrayPrediction: MutableList = ArrayList()
- val now = dateUtil.now().toDouble()
- overviewData.maxIAValue = 0.0
-
- val bgiArrayHist: MutableList = ArrayList()
- val bgiArrayPrediction: MutableList = ArrayList()
- overviewData.maxBGIValue = Double.MIN_VALUE
-
- val devArray: MutableList = ArrayList()
- overviewData.maxDevValueFound = Double.MIN_VALUE
-
- val ratioArray: MutableList = ArrayList()
- overviewData.maxRatioValueFound = 5.0 //even if sens data equals 0 for all the period, minimum scale is between 95% and 105%
- overviewData.minRatioValueFound = -5.0
-
- val dsMaxArray: MutableList = ArrayList()
- val dsMinArray: MutableList = ArrayList()
- overviewData.maxFromMaxValueFound = Double.MIN_VALUE
- overviewData.maxFromMinValueFound = Double.MIN_VALUE
-
- val adsData = iobCobCalculator.ads.clone()
-
- while (time <= overviewData.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, overviewData.iobScale))
- iobArray.add(ScaledDataPoint(time, iob.iob, overviewData.iobScale))
- overviewData.maxIobValueFound = maxOf(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, overviewData.iobScale))
- absIobArray.add(ScaledDataPoint(time, absIob.iob, overviewData.iobScale))
- overviewData.maxIobValueFound = maxOf(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(), overviewData.cobScale))
- cobArray.add(ScaledDataPoint(time, cob.toDouble(), overviewData.cobScale))
- overviewData.maxCobValueFound = max(overviewData.maxCobValueFound, cob.toDouble())
- lastCob = cob
- }
- if (autosensData.failoverToMinAbsorbtionRate) {
- autosensData.setScale(overviewData.cobScale)
- autosensData.setChartTime(time)
- minFailOverActiveList.add(autosensData)
- }
- }
-
- // ACTIVITY
- if (time <= now) actArrayHist.add(ScaledDataPoint(time, iob.activity, overviewData.actScale))
- else actArrayPrediction.add(ScaledDataPoint(time, iob.activity, overviewData.actScale))
- overviewData.maxIAValue = max(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, overviewData.bgiScale))
- else bgiArrayPrediction.add(ScaledDataPoint(time, bgi, overviewData.bgiScale))
- overviewData.maxBGIValue = max(overviewData.maxBGIValue, max(abs(bgi), deviation))
-
- // DEVIATIONS
- if (autosensData != null) {
- var color = resourceHelper.gc(R.color.deviationblack) // "="
- if (autosensData.type == "" || autosensData.type == "non-meal") {
- if (autosensData.pastSensitivity == "C") color = resourceHelper.gc(R.color.deviationgrey)
- if (autosensData.pastSensitivity == "+") color = resourceHelper.gc(R.color.deviationgreen)
- if (autosensData.pastSensitivity == "-") color = resourceHelper.gc(R.color.deviationred)
- } else if (autosensData.type == "uam") {
- color = resourceHelper.gc(R.color.uam)
- } else if (autosensData.type == "csf") {
- color = resourceHelper.gc(R.color.deviationgrey)
- }
- devArray.add(DeviationDataPoint(time.toDouble(), autosensData.deviation, color, overviewData.devScale))
- overviewData.maxDevValueFound = maxOf(overviewData.maxDevValueFound, abs(autosensData.deviation), abs(bgi))
- }
-
- // RATIO
- if (autosensData != null) {
- ratioArray.add(ScaledDataPoint(time, 100.0 * (autosensData.autosensResult.ratio - 1), overviewData.ratioScale))
- overviewData.maxRatioValueFound = max(overviewData.maxRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
- overviewData.minRatioValueFound = min(overviewData.minRatioValueFound, 100.0 * (autosensData.autosensResult.ratio - 1))
- }
-
- // DEV SLOPE
- if (autosensData != null) {
- dsMaxArray.add(ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, overviewData.dsMaxScale))
- dsMinArray.add(ScaledDataPoint(time, autosensData.slopeFromMinDeviation, overviewData.dsMinScale))
- overviewData.maxFromMaxValueFound = max(overviewData.maxFromMaxValueFound, abs(autosensData.slopeFromMaxDeviation))
- overviewData.maxFromMinValueFound = max(overviewData.maxFromMinValueFound, abs(autosensData.slopeFromMinDeviation))
- }
-
- time += 5 * 60 * 1000L
- }
- // IOB
- overviewData.iobSeries = FixedLineGraphSeries(Array(iobArray.size) { i -> iobArray[i] }).also {
- it.isDrawBackground = true
- it.backgroundColor = -0x7f000001 and resourceHelper.gc(R.color.iob) //50%
- it.color = resourceHelper.gc(R.color.iob)
- it.thickness = 3
- }
- overviewData.absIobSeries = FixedLineGraphSeries(Array(absIobArray.size) { i -> absIobArray[i] }).also {
- it.isDrawBackground = true
- it.backgroundColor = -0x7f000001 and resourceHelper.gc(R.color.iob) //50%
- it.color = resourceHelper.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 = ArrayList()
- val iobPredictionArray = iobCobCalculator.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
- for (i in iobPredictionArray) {
- iobPrediction.add(i.setColor(resourceHelper.gc(R.color.iobPredAS)))
- overviewData.maxIobValueFound = max(overviewData.maxIobValueFound, abs(i.iob))
- }
- overviewData.iobPredictions1Series = PointsWithLabelGraphSeries(Array(iobPrediction.size) { i -> iobPrediction[i] })
- val iobPrediction2: MutableList = ArrayList()
- val iobPredictionArray2 = iobCobCalculator.calculateIobArrayForSMB(AutosensResult(), SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
- for (i in iobPredictionArray2) {
- iobPrediction2.add(i.setColor(resourceHelper.gc(R.color.iobPred)))
- overviewData.maxIobValueFound = max(overviewData.maxIobValueFound, abs(i.iob))
- }
- overviewData.iobPredictions2Series = PointsWithLabelGraphSeries(Array(iobPrediction2.size) { i -> iobPrediction2[i] })
- aapsLogger.debug(LTag.AUTOSENS, "IOB prediction for AS=" + DecimalFormatter.to2Decimal(lastAutosensResult.ratio) + ": " + iobCobCalculator.iobArrayToString(iobPredictionArray))
- aapsLogger.debug(LTag.AUTOSENS, "IOB prediction for AS=" + DecimalFormatter.to2Decimal(1.0) + ": " + iobCobCalculator.iobArrayToString(iobPredictionArray2))
- } else {
- overviewData.iobPredictions1Series = PointsWithLabelGraphSeries()
- overviewData.iobPredictions2Series = PointsWithLabelGraphSeries()
- }
-
- // COB
- overviewData.cobSeries = FixedLineGraphSeries(Array(cobArray.size) { i -> cobArray[i] }).also {
- it.isDrawBackground = true
- it.backgroundColor = -0x7f000001 and resourceHelper.gc(R.color.cob) //50%
- it.color = resourceHelper.gc(R.color.cob)
- it.thickness = 3
- }
- overviewData.cobMinFailOverSeries = PointsWithLabelGraphSeries(Array(minFailOverActiveList.size) { i -> minFailOverActiveList[i] })
-
- // ACTIVITY
- overviewData.activitySeries = FixedLineGraphSeries(Array(actArrayHist.size) { i -> actArrayHist[i] }).also {
- it.isDrawBackground = false
- it.color = resourceHelper.gc(R.color.activity)
- it.thickness = 3
- }
- 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 = resourceHelper.gc(R.color.activity)
- })
- }
-
- // BGI
- overviewData.minusBgiSeries = FixedLineGraphSeries(Array(bgiArrayHist.size) { i -> bgiArrayHist[i] }).also {
- it.isDrawBackground = false
- it.color = resourceHelper.gc(R.color.bgi)
- it.thickness = 3
- }
- 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 = resourceHelper.gc(R.color.bgi)
- })
- }
-
- // DEVIATIONS
- overviewData.deviationsSeries = BarGraphSeries(Array(devArray.size) { i -> devArray[i] }).also {
- it.setValueDependentColor { data: DeviationDataPoint -> data.color }
- }
-
- // RATIO
- overviewData.ratioSeries = LineGraphSeries(Array(ratioArray.size) { i -> ratioArray[i] }).also {
- it.color = resourceHelper.gc(R.color.ratio)
- it.thickness = 3
- }
-
- // DEV SLOPE
- overviewData.dsMaxSeries = LineGraphSeries(Array(dsMaxArray.size) { i -> dsMaxArray[i] }).also {
- it.color = resourceHelper.gc(R.color.devslopepos)
- it.thickness = 3
- }
- overviewData.dsMinSeries = LineGraphSeries(Array(dsMinArray.size) { i -> dsMinArray[i] }).also {
- it.color = resourceHelper.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 {
- 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 List.filterTimeframe(fromTime: Long, endTime: Long): List =
- filter { it.x + it.duration >= fromTime && it.x <= endTime }
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt
index cbc021b421..0ffe4a9cb3 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt
@@ -27,16 +27,16 @@ import kotlin.math.max
class GraphData(
injector: HasAndroidInjector,
- private val graph: GraphView
+ private val graph: GraphView,
+ private val overviewData: OverviewData
) {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var defaultValueHelper: DefaultValueHelper
- @Inject lateinit var overviewData: OverviewData
- var maxY = Double.MIN_VALUE
+ private var maxY = Double.MIN_VALUE
private var minY = Double.MAX_VALUE
private val units: GlucoseUnit
private val series: MutableList> = ArrayList()
@@ -214,7 +214,7 @@ class GraphData(
graph.gridLabelRenderer.numHorizontalLabels = 7 // only 7 because of the space
}
- internal fun addSeries(s: Series<*>) = series.add(s)
+ private fun addSeries(s: Series<*>) = series.add(s)
fun performUpdate() {
// clear old data
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.kt
index d577666d27..51ef6da52f 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.kt
@@ -99,7 +99,7 @@ class IobCobOref1Thread internal constructor(
// start from oldest to be able sub cob
for (i in bucketedData.size - 4 downTo 0) {
val progress = i.toString() + if (buildHelper.isDev()) " ($from)" else ""
- rxBus.send(EventIobCalculationProgress(progress))
+ rxBus.send(EventIobCalculationProgress(progress, cause))
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
iobCobCalculatorPlugin.stopCalculationTrigger = false
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from")
@@ -325,7 +325,7 @@ class IobCobOref1Thread internal constructor(
}.start()
} finally {
mWakeLock?.release()
- rxBus.send(EventIobCalculationProgress(""))
+ rxBus.send(EventIobCalculationProgress("", cause))
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.kt
index e6fa48cca2..cd3c12c438 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.kt
@@ -98,7 +98,7 @@ class IobCobThread @Inject internal constructor(
// start from oldest to be able sub cob
for (i in bucketedData.size - 4 downTo 0) {
val progress = i.toString() + if (buildHelper.isDev()) " ($from)" else ""
- rxBus.send(EventIobCalculationProgress(progress))
+ rxBus.send(EventIobCalculationProgress(progress, cause))
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
iobCobCalculatorPlugin.stopCalculationTrigger = false
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from")
@@ -272,7 +272,7 @@ class IobCobThread @Inject internal constructor(
}.start()
} finally {
mWakeLock?.release()
- rxBus.send(EventIobCalculationProgress(""))
+ rxBus.send(EventIobCalculationProgress("", cause))
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventIobCalculationProgress.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventIobCalculationProgress.kt
index f2e8059b10..a5326e4ad3 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventIobCalculationProgress.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventIobCalculationProgress.kt
@@ -2,4 +2,4 @@ package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
import info.nightscout.androidaps.events.Event
-class EventIobCalculationProgress(var progress: String) : Event()
\ No newline at end of file
+class EventIobCalculationProgress(val progress: String, val cause: Event?) : Event()
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt
index 31f01df6c1..cef0babae1 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt
@@ -70,7 +70,7 @@ class LocalProfileFragment : DaggerFragment() {
}
private fun sumLabel(): String {
- val profile = localProfilePlugin.createProfileStore().getDefaultProfile()
+ val profile = localProfilePlugin.profile?.getDefaultProfile()
val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0
return " ∑" + DecimalFormatter.to2Decimal(sum) + resourceHelper.gs(R.string.insulin_unit_shortname)
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt
index 42afbb4c5c..2feeab89d8 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt
@@ -139,6 +139,7 @@ class LocalProfilePlugin @Inject constructor(
}
sp.putInt(Constants.LOCAL_PROFILE + "_profiles", numOfProfiles)
+ sp.putLong(R.string.key_local_profile_last_change, dateUtil.now())
createAndStoreConvertedProfile()
isEdited = false
aapsLogger.debug(LTag.PROFILE, "Storing settings: " + rawProfile?.data.toString())
@@ -148,12 +149,9 @@ class LocalProfilePlugin @Inject constructor(
val name = it.name ?: "."
if (name.contains(".")) namesOK = false
}
- if (namesOK)
- sp.putLong(R.string.key_local_profile_last_change, dateUtil.now())
- else
- activity?.let {
- OKDialog.show(it, "", resourceHelper.gs(R.string.profilenamecontainsdot))
- }
+ if (!namesOK) activity?.let {
+ OKDialog.show(it, "", resourceHelper.gs(R.string.profilenamecontainsdot))
+ }
}
@Synchronized
@@ -372,7 +370,8 @@ class LocalProfilePlugin @Inject constructor(
}
}
if (numOfProfiles > 0) json.put("defaultProfile", currentProfile()?.name)
- json.put("startDate", dateUtil.toISOAsUTC(dateUtil.now()))
+ val startDate = sp.getLong(R.string.key_local_profile_last_change, dateUtil.now())
+ json.put("startDate", dateUtil.toISOAsUTC(startDate))
json.put("store", store)
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
@@ -412,11 +411,19 @@ class LocalProfilePlugin @Inject constructor(
val profileJson = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
if (sp.getBoolean(R.string.key_ns_receive_profile_store, false) || config.NSCLIENT) {
- localProfilePlugin.loadFromStore(ProfileStore(injector, profileJson, dateUtil))
- aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
- return Result.success(workDataOf("Data" to profileJson.toString().substring(0..min(5000, profileJson.length()))))
+ val store = ProfileStore(injector, profileJson, dateUtil)
+ val startDate = store.getStartDate()
+ val lastLocalChange = sp.getLong(R.string.key_local_profile_last_change, 0)
+ aapsLogger.debug(LTag.PROFILE, "Received profileStore: StartDate: $startDate Local last modification: $lastLocalChange")
+ @Suppress("LiftReturnOrAssignment")
+ if (startDate > lastLocalChange || startDate % 1000 == 0L) {// whole second means edited in NS
+ localProfilePlugin.loadFromStore(store)
+ aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
+ return Result.success(workDataOf("Data" to profileJson.toString().substring(0..min(5000, profileJson.length()))))
+ } else
+ return Result.success(workDataOf("Result" to "Unchanged. Ignoring"))
}
- return Result.success()
+ return Result.success(workDataOf("Result" to "Sync not enabled"))
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt
index 6b6cb588e8..d744d81340 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt
@@ -94,7 +94,7 @@ class DexcomPlugin @Inject constructor(
override fun doWork(): Result {
var ret = Result.success()
- if (!dexcomPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success()
+ if (!dexcomPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success(workDataOf("Result" to "Plugin not enabled"))
val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
try {
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt
index 434e5eb873..a6c51cf5de 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt
@@ -69,7 +69,7 @@ class EversensePlugin @Inject constructor(
override fun doWork(): Result {
var ret = Result.success()
- if (!eversensePlugin.isEnabled(PluginType.BGSOURCE)) return Result.success()
+ if (!eversensePlugin.isEnabled(PluginType.BGSOURCE)) return Result.success(workDataOf("Result" to "Plugin not enabled"))
val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
if (bundle.containsKey("currentCalibrationPhase")) aapsLogger.debug(LTag.BGSOURCE, "currentCalibrationPhase: " + bundle.getString("currentCalibrationPhase"))
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt
index 36724eb4b5..d2b167a43d 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt
@@ -56,7 +56,7 @@ class GlimpPlugin @Inject constructor(
override fun doWork(): Result {
var ret = Result.success()
- if (!glimpPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success()
+ if (!glimpPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success(workDataOf("Result" to "Plugin not enabled"))
aapsLogger.debug(LTag.BGSOURCE, "Received Glimp Data: $inputData}")
val glucoseValues = mutableListOf()
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt
index 52874bb335..a0aa888901 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt
@@ -115,7 +115,7 @@ class NSClientSourcePlugin @Inject constructor(
override fun doWork(): Result {
var ret = Result.success()
- if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(R.string.key_ns_receive_cgm, true) && !dexcomPlugin.isEnabled()) return Result.success()
+ if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(R.string.key_ns_receive_cgm, true) && !dexcomPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Sync not enabled"))
val sgvs = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt
index 17aefac5b5..fa7e0a278a 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt
@@ -60,7 +60,7 @@ class PoctechPlugin @Inject constructor(
override fun doWork(): Result {
var ret = Result.success()
- if (!poctechPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success()
+ if (!poctechPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success(workDataOf("Result" to "Plugin not enabled"))
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $inputData")
try {
val glucoseValues = mutableListOf()
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt
index cf6fce3da5..52773e1d76 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt
@@ -59,7 +59,7 @@ class TomatoPlugin @Inject constructor(
override fun doWork(): Result {
var ret = Result.success()
- if (!tomatoPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success()
+ if (!tomatoPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success(workDataOf("Result" to "Plugin not enabled"))
val glucoseValues = mutableListOf()
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
timestamp = inputData.getLong("com.fanqies.tomatofn.Extras.Time", 0),
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt
index 622d69c284..bbb8b2c7e1 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt
@@ -73,7 +73,7 @@ class XdripPlugin @Inject constructor(
override fun doWork(): Result {
var ret = Result.success()
- if (!xdripPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success()
+ if (!xdripPlugin.isEnabled(PluginType.BGSOURCE)) return Result.success(workDataOf("Result" to "Plugin not enabled"))
val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java
index d994c0475f..04345c3c6d 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java
@@ -67,7 +67,6 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
) {
super(new PluginDescription()
.mainType(PluginType.TREATMENT)
- .fragmentClass(TreatmentsFragment.class.getName())
.pluginIcon(R.drawable.ic_treatments)
.pluginName(R.string.treatments)
.shortName(R.string.treatments_shortname)
diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt
index 448e917ae9..d759844d87 100644
--- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt
+++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt
@@ -566,11 +566,12 @@ open class CommandQueue @Inject constructor(
return HtmlHelper.fromHtml(s)
}
- override fun isThisProfileSet(profile: Profile): Boolean {
- val result = activePlugin.activePump.isThisProfileSet(profile)
+ override fun isThisProfileSet(requestedProfile: Profile): Boolean {
+ val runningProfile = profileFunction.getProfile() ?: return false
+ val result = activePlugin.activePump.isThisProfileSet(requestedProfile) && requestedProfile.isEqual(runningProfile)
if (!result) {
aapsLogger.debug(LTag.PUMPQUEUE, "Current profile: ${profileFunction.getProfile()}")
- aapsLogger.debug(LTag.PUMPQUEUE, "New profile: $profile")
+ aapsLogger.debug(LTag.PUMPQUEUE, "New profile: $requestedProfile")
}
return result
}
diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.kt b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.kt
index 1b78360966..48f073e804 100644
--- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.kt
+++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.kt
@@ -119,18 +119,18 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
private fun checkPump() {
val pump = activePlugin.activePump
val ps = profileFunction.getRequestedProfile() ?: return
- val profile = ProfileSealed.PS(ps)
+ val requestedProfile = ProfileSealed.PS(ps)
+ val runningProfile = profileFunction.getProfile()
val lastConnection = pump.lastDataTime()
val isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis()
- val isBasalOutdated = abs(profile.getBasal() - pump.baseBasalRate) > pump.pumpDescription.basalStep
+ val isBasalOutdated = abs(requestedProfile.getBasal() - pump.baseBasalRate) > pump.pumpDescription.basalStep
aapsLogger.debug(LTag.CORE, "Last connection: " + dateUtil.dateAndTimeString(lastConnection))
// sometimes keep alive broadcast stops
// as as workaround test if readStatus was requested before an alarm is generated
if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) {
localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loopPlugin.isDisconnected)
}
- if (!pump.isThisProfileSet(profile) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)
- || profileFunction.getProfile() == null) {
+ if (runningProfile == null || ((!pump.isThisProfileSet(requestedProfile) || !requestedProfile.isEqual(runningProfile)) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE))) {
rxBus.send(EventProfileSwitchChanged())
} else if (isStatusOutdated && !pump.isBusy()) {
lastReadStatus = System.currentTimeMillis()
diff --git a/app/src/main/res/layout/activity_historybrowse.xml b/app/src/main/res/layout/activity_historybrowse.xml
index 98ce50f0c4..65bd506f7e 100644
--- a/app/src/main/res/layout/activity_historybrowse.xml
+++ b/app/src/main/res/layout/activity_historybrowse.xml
@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context="info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity">
+ tools:context="info.nightscout.androidaps.activities.HistoryBrowseActivity">
diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml
index 920d10f4ee..e66a0c9c62 100644
--- a/app/src/main/res/layout/localprofile_fragment.xml
+++ b/app/src/main/res/layout/localprofile_fragment.xml
@@ -239,7 +239,7 @@
android:layout_marginBottom="10dp"
android:orientation="vertical" />
-
+ tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsBolusCarbsFragment">
+ tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsCareportalFragment">
+ tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment">
+ tools:context="info.nightscout.androidaps.activities.TreatmentsActivity">
+ tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFragment">
+ tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment">
+ tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment">
+ tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsUserEntryFragment">
+
- ): Boolean
fun isCustomCommandInQueue(customCommandType: Class): Boolean
fun spannedStatus(): Spanned
- fun isThisProfileSet(profile: Profile): Boolean
+ fun isThisProfileSet(requestedProfile: Profile): Boolean
}
\ No newline at end of file
diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileStore.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileStore.kt
index 91a00c4dc4..5884128606 100644
--- a/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileStore.kt
+++ b/core/src/main/java/info/nightscout/androidaps/interfaces/ProfileStore.kt
@@ -31,6 +31,15 @@ class ProfileStore(val injector: HasAndroidInjector, val data: JSONObject, val d
return null
}
+ fun getStartDate(): Long {
+ val iso = JsonHelper.safeGetString(data, "startDate") ?: return 0
+ return try {
+ dateUtil.fromISODateString(iso)
+ } catch (e: Exception) {
+ 0
+ }
+ }
+
fun getDefaultProfile(): PureProfile? = getDefaultProfileName()?.let { getSpecificProfile(it) }
fun getDefaultProfileJson(): JSONObject? = getDefaultProfileName()?.let { getSpecificProfileJson(it) }
diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/bolusInfo/DetailedBolusInfoStorage.kt b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/bolusInfo/DetailedBolusInfoStorage.kt
index 062d41191f..57a732cbc3 100644
--- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/bolusInfo/DetailedBolusInfoStorage.kt
+++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/bolusInfo/DetailedBolusInfoStorage.kt
@@ -29,7 +29,7 @@ class DetailedBolusInfoStorage @Inject constructor(
val d = store[i]
//aapsLogger.debug(LTag.PUMP, "Existing bolus info: " + store[i])
if (bolusTime > d.timestamp - T.mins(1).msecs() && bolusTime < d.timestamp + T.mins(1).msecs() && abs(store[i].insulin - bolus) < 0.01) {
- aapsLogger.debug(LTag.PUMP, "Using & removing bolus info: ${store[i]}")
+ aapsLogger.debug(LTag.PUMP, "Using & removing bolus info for time $bolusTime: ${store[i]}")
store.removeAt(i)
return d
}
@@ -38,22 +38,22 @@ class DetailedBolusInfoStorage @Inject constructor(
for (i in store.indices) {
val d = store[i]
if (bolusTime > d.timestamp - T.mins(1).msecs() && bolusTime < d.timestamp + T.mins(1).msecs() && bolus <= store[i].insulin + 0.01) {
- aapsLogger.debug(LTag.PUMP, "Using TIME-ONLY & removing bolus info: ${store[i]}")
+ aapsLogger.debug(LTag.PUMP, "Using TIME-ONLY & removing bolus info for time $bolusTime: ${store[i]}")
store.removeAt(i)
return d
}
}
// If not found, use last record if amount is the same
- if (store.size > 0) {
- val d = store[store.size - 1]
- if (abs(d.insulin - bolus) < 0.01) {
- aapsLogger.debug(LTag.PUMP, "Using LAST & removing bolus info: $d")
- store.removeAt(store.size - 1)
- return d
- }
- }
+ // if (store.size > 0) {
+ // val d = store[store.size - 1]
+ // if (abs(d.insulin - bolus) < 0.01) {
+ // aapsLogger.debug(LTag.PUMP, "Using LAST & removing bolus info for time $bolusTime: $d")
+ // store.removeAt(store.size - 1)
+ // return d
+ // }
+ // }
//Not found
- //aapsLogger.debug(LTag.PUMP, "Bolus info not found")
+ aapsLogger.debug(LTag.PUMP, "Bolus info not found for time $bolusTime")
return null
}
}
\ No newline at end of file
diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/ProfileGraph.kt b/core/src/main/java/info/nightscout/androidaps/utils/ui/ProfileGraph.kt
similarity index 96%
rename from core/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/ProfileGraph.kt
rename to core/src/main/java/info/nightscout/androidaps/utils/ui/ProfileGraph.kt
index 0623cbaf40..61e4f64a74 100644
--- a/core/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/ProfileGraph.kt
+++ b/core/src/main/java/info/nightscout/androidaps/utils/ui/ProfileGraph.kt
@@ -1,7 +1,6 @@
-package info.nightscout.androidaps.plugins.treatments.fragments
+package info.nightscout.androidaps.utils.ui
import android.content.Context
-import android.graphics.Color
import android.util.AttributeSet
import com.jjoe64.graphview.GraphView
import com.jjoe64.graphview.series.DataPoint
@@ -9,7 +8,7 @@ import com.jjoe64.graphview.series.LineGraphSeries
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.utils.Round
-import java.util.*
+import java.util.ArrayList
import kotlin.math.max
class ProfileGraph : GraphView {
diff --git a/core/src/main/res/layout/dialog_profileviewer.xml b/core/src/main/res/layout/dialog_profileviewer.xml
index 822213e76c..7f02c1457e 100644
--- a/core/src/main/res/layout/dialog_profileviewer.xml
+++ b/core/src/main/res/layout/dialog_profileviewer.xml
@@ -371,7 +371,7 @@
- ? = null
@@ -326,13 +323,16 @@ class BLEComm @Inject internal constructor(
}
private val readBuffer = ByteArray(1024)
- private var bufferLength = 0
+ @Volatile private var bufferLength = 0
private fun addToReadBuffer(buffer: ByteArray) {
//log.debug("addToReadBuffer " + DanaRS_Packet.toHexString(buffer));
if (buffer.isEmpty()) {
return
}
+ if (bufferLength == 1024) {
+ aapsLogger.debug(LTag.PUMPBTCOMM, "1024 XXXXXXXXXXXXXX")
+ }
synchronized(readBuffer) {
// Append incoming data to input buffer
System.arraycopy(buffer, 0, readBuffer, bufferLength, buffer.size)
@@ -342,21 +342,23 @@ class BLEComm @Inject internal constructor(
@kotlin.ExperimentalStdlibApi
private fun readDataParsing(receivedData: ByteArray) {
- //aapsLogger.debug(LTag.PUMPBTCOMM, "readDataParsing")
+ //aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< readDataParsing " + DanaRS_Packet.toHexString(receivedData))
var startSignatureFound = false
var packetIsValid = false
var isProcessing: Boolean
isProcessing = true
- var inputBuffer: ByteArray? = null
+ var inputBuffer: ByteArray?
// decrypt 2nd level after successful connection
- val incomingBuffer = if (encryption == EncryptionType.ENCRYPTION_RSv3 && isConnected)
- bleEncryption.decryptSecondLevelPacket(receivedData).also {
- encryptedDataRead = true
- sp.putLong(R.string.key_rs_last_clear_key_request, 0L)
- }
- else receivedData
+ val incomingBuffer =
+ if (isConnected && (encryption == EncryptionType.ENCRYPTION_RSv3 || encryption == EncryptionType.ENCRYPTION_BLE5))
+ bleEncryption.decryptSecondLevelPacket(receivedData).also {
+ encryptedDataRead = true
+ sp.putLong(R.string.key_rs_last_clear_key_request, 0L)
+ }
+ else receivedData
addToReadBuffer(incomingBuffer)
+ //aapsLogger.debug(LTag.PUMPBTCOMM, "incomingBuffer " + DanaRS_Packet.toHexString(incomingBuffer))
while (isProcessing) {
var length = 0
@@ -386,58 +388,29 @@ class BLEComm @Inject internal constructor(
// Verify packed end [5A 5A]
if (readBuffer[length + 5] == PACKET_END_BYTE && readBuffer[length + 6] == PACKET_END_BYTE) {
packetIsValid = true
+ } else if (readBuffer[length + 5] == readBuffer[length + 6]) {
+ // BLE5
+ packetIsValid = true
+ readBuffer[length + 5] = PACKET_END_BYTE
+ readBuffer[length + 6] = PACKET_END_BYTE
}
}
- // packet can be BLE5 encrypted too
- if (!packetIsValid && encryption == EncryptionType.ENCRYPTION_BLE5) {
- var startIndex: Int = -1
- // Find encrypted packet start [73 73]
- if (bufferLength >= 6) {
- for (idxStartByte in 0 until bufferLength - 2) {
- if (readBuffer[idxStartByte] == BLE5_PACKET_START_BYTE && readBuffer[idxStartByte + 1] == BLE5_PACKET_START_BYTE) {
- if (idxStartByte > 0) {
- // if buffer doesn't start with signature remove the leading trash
- aapsLogger.debug(LTag.PUMPBTCOMM, "Shifting the input buffer by $idxStartByte bytes")
- System.arraycopy(readBuffer, idxStartByte, readBuffer, 0, bufferLength - idxStartByte)
- bufferLength -= idxStartByte
- }
- startIndex = idxStartByte
- break
- }
- }
- }
- // 73 73 ENCRYPTED CONTENT BF BF
- if (startIndex != -1) {
- for (idxEndByte in 5..bufferLength - 2) {
- if (readBuffer[idxEndByte] == BLE5_PACKET_END_BYTE && readBuffer[idxEndByte + 1] == BLE5_PACKET_END_BYTE) {
- length = idxEndByte - startIndex + 2 - 7
- packetIsValid = true
- encryptedDataRead = true
- break
- }
- }
- }
- }
- if (packetIsValid) {
- inputBuffer = ByteArray(length + 7)
- // copy packet to input buffer
- System.arraycopy(readBuffer, 0, inputBuffer, 0, length + 7)
- // Cut off the message from readBuffer
- try {
- System.arraycopy(readBuffer, length + 7, readBuffer, 0, bufferLength - (length + 7))
- } catch (e: Exception) {
- aapsLogger.error("length: " + length + "bufferLength: " + bufferLength)
- throw e
- }
- bufferLength -= length + 7
- // now we have encrypted packet in inputBuffer
- }
- }
- if (packetIsValid && encryptedDataRead && encryption == EncryptionType.ENCRYPTION_BLE5) {
- inputBuffer = bleEncryption.decryptSecondLevelPacket(inputBuffer)
}
if (packetIsValid) {
- // aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< PROCESSING: " + DanaRS_Packet.toHexString(inputBuffer))
+ inputBuffer = ByteArray(length + 7)
+ // copy packet to input buffer
+ System.arraycopy(readBuffer, 0, inputBuffer, 0, length + 7)
+ // Cut off the message from readBuffer
+ try {
+ System.arraycopy(readBuffer, length + 7, readBuffer, 0, bufferLength - (length + 7))
+ } catch (e: Exception) {
+ aapsLogger.error("length: " + length + "bufferLength: " + bufferLength)
+ throw e
+ }
+ bufferLength -= length + 7
+ // now we have encrypted packet in inputBuffer
+
+ //aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< PROCESSING: " + DanaRS_Packet.toHexString(inputBuffer))
// decrypt the packet
bleEncryption.getDecryptedPacket(inputBuffer)?.let { decryptedBuffer ->
if (decryptedBuffer[0] == BleEncryption.DANAR_PACKET__TYPE_ENCRYPTION_RESPONSE.toByte()) {
diff --git a/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so b/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so
index ce5fff9e71..7c0c49b7e8 100644
Binary files a/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so and b/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so differ
diff --git a/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so b/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so
index eab5691db8..4778aca663 100644
Binary files a/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so and b/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so differ
diff --git a/danars/src/main/jniLibs/x86/libBleEncryption.so b/danars/src/main/jniLibs/x86/libBleEncryption.so
index 9885d73606..e5ef3a17a4 100644
Binary files a/danars/src/main/jniLibs/x86/libBleEncryption.so and b/danars/src/main/jniLibs/x86/libBleEncryption.so differ
diff --git a/danars/src/main/jniLibs/x86_64/libBleEncryption.so b/danars/src/main/jniLibs/x86_64/libBleEncryption.so
index 00e47ca4d3..e4c02d8842 100644
Binary files a/danars/src/main/jniLibs/x86_64/libBleEncryption.so and b/danars/src/main/jniLibs/x86_64/libBleEncryption.so differ
diff --git a/database/src/main/java/info/nightscout/androidaps/database/daos/GlucoseValueDao.kt b/database/src/main/java/info/nightscout/androidaps/database/daos/GlucoseValueDao.kt
index 27cde3dbe4..bda5c63b2f 100644
--- a/database/src/main/java/info/nightscout/androidaps/database/daos/GlucoseValueDao.kt
+++ b/database/src/main/java/info/nightscout/androidaps/database/daos/GlucoseValueDao.kt
@@ -16,7 +16,7 @@ internal interface GlucoseValueDao : TraceableDao {
@Query("DELETE FROM $TABLE_GLUCOSE_VALUES")
override fun deleteAllEntries()
- @Query("SELECT * FROM $TABLE_GLUCOSE_VALUES ORDER BY id DESC limit 1")
+ @Query("SELECT * FROM $TABLE_GLUCOSE_VALUES WHERE isValid = 1 AND referenceId IS NULL ORDER BY id DESC limit 1")
fun getLast(): Maybe
@Query("SELECT id FROM $TABLE_GLUCOSE_VALUES ORDER BY id DESC limit 1")