Merge branch 'dev' into FixSensScale
This commit is contained in:
commit
3a24af1a4c
|
@ -68,7 +68,8 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".plugins.general.maintenance.activities.PrefImportListActivity" />
|
<activity android:name=".plugins.general.maintenance.activities.PrefImportListActivity" />
|
||||||
<activity android:name=".historyBrowser.HistoryBrowseActivity" />
|
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||||
|
<activity android:name=".activities.TreatmentsActivity" />
|
||||||
<activity android:name=".activities.SurveyActivity" />
|
<activity android:name=".activities.SurveyActivity" />
|
||||||
<activity android:name=".activities.ProfileHelperActivity"
|
<activity android:name=".activities.ProfileHelperActivity"
|
||||||
android:theme="@style/ProfileHelperAppTheme" />
|
android:theme="@style/ProfileHelperAppTheme" />
|
||||||
|
|
|
@ -27,18 +27,14 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
import com.joanzapata.iconify.Iconify
|
import com.joanzapata.iconify.Iconify
|
||||||
import com.joanzapata.iconify.fonts.FontAwesomeModule
|
import com.joanzapata.iconify.fonts.FontAwesomeModule
|
||||||
import dev.doubledot.doki.ui.DokiActivity
|
import dev.doubledot.doki.ui.DokiActivity
|
||||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
import info.nightscout.androidaps.activities.*
|
||||||
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.database.entities.UserEntry.Action
|
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||||
import info.nightscout.androidaps.databinding.ActivityMainBinding
|
import info.nightscout.androidaps.databinding.ActivityMainBinding
|
||||||
import info.nightscout.androidaps.events.EventAppExit
|
import info.nightscout.androidaps.events.EventAppExit
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
import info.nightscout.androidaps.events.EventRebuildTabs
|
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.ActivePlugin
|
||||||
import info.nightscout.androidaps.interfaces.Config
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
import info.nightscout.androidaps.interfaces.IconsProvider
|
import info.nightscout.androidaps.interfaces.IconsProvider
|
||||||
|
@ -291,6 +287,11 @@ class MainActivity : NoSplashAppCompatActivity() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.nav_treatments -> {
|
||||||
|
startActivity(Intent(this, TreatmentsActivity::class.java))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
R.id.nav_setupwizard -> {
|
R.id.nav_setupwizard -> {
|
||||||
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, {
|
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, {
|
||||||
startActivity(Intent(this, SetupWizardActivity::class.java))
|
startActivity(Intent(this, SetupWizardActivity::class.java))
|
||||||
|
|
|
@ -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<GraphView>()
|
||||||
|
private val secondaryGraphsLabel = ArrayList<TextView>()
|
||||||
|
|
||||||
|
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<GraphData> = 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,53 +1,28 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments
|
package info.nightscout.androidaps.activities
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentTransaction
|
import androidx.fragment.app.FragmentTransaction
|
||||||
import dagger.android.support.DaggerFragment
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.fragments.*
|
||||||
import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding
|
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.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
|
||||||
import io.reactivex.rxkotlin.plusAssign
|
|
||||||
import javax.inject.Inject
|
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 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
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
// This property is only valid between onCreateView and
|
binding = TreatmentsFragmentBinding.inflate(layoutInflater)
|
||||||
// onDestroyView.
|
setContentView(binding.root)
|
||||||
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)
|
|
||||||
|
|
||||||
binding.tempBasals.visibility = buildHelper.isEngineeringMode().toVisibility()
|
binding.tempBasals.visibility = buildHelper.isEngineeringMode().toVisibility()
|
||||||
binding.extendedBoluses.visibility = (buildHelper.isEngineeringMode() && !activePlugin.activePump.isFakingTempsByExtendedBoluses).toVisibility()
|
binding.extendedBoluses.visibility = (buildHelper.isEngineeringMode() && !activePlugin.activePump.isFakingTempsByExtendedBoluses).toVisibility()
|
||||||
|
@ -84,33 +59,10 @@ class TreatmentsFragment : DaggerFragment() {
|
||||||
setBackgroundColorOnSelected(binding.treatments)
|
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) {
|
private fun setFragment(selectedFragment: Fragment) {
|
||||||
childFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.replace(R.id.fragment_container, selectedFragment) // f2_container is your FrameLayout container
|
.replace(R.id.fragment_container, selectedFragment)
|
||||||
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
|
||||||
.addToBackStack(null)
|
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +77,4 @@ class TreatmentsFragment : DaggerFragment() {
|
||||||
selected.setBackgroundColor(resourceHelper.gc(R.color.tabBgColorSelected))
|
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()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.activities.fragments
|
||||||
|
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.activities.fragments
|
||||||
|
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.os.Bundle
|
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.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||||
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
|
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.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.activities.fragments
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.DialogInterface
|
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.LTag
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
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.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.activities.fragments
|
||||||
|
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.os.Bundle
|
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.LocalProfilePlugin
|
||||||
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
||||||
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
|
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.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.activities.fragments
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.DialogInterface
|
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.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||||
import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui
|
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.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.activities.fragments
|
||||||
|
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.graphics.Paint
|
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.LTag
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
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.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.activities.fragments
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
|
@ -4,7 +4,7 @@ import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import info.nightscout.androidaps.MainActivity
|
import info.nightscout.androidaps.MainActivity
|
||||||
import info.nightscout.androidaps.activities.*
|
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.maintenance.activities.LogSettingActivity
|
||||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
|
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
|
||||||
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
|
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
|
||||||
|
@ -15,6 +15,7 @@ import info.nightscout.androidaps.setupwizard.SetupWizardActivity
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
abstract class ActivitiesModule {
|
abstract class ActivitiesModule {
|
||||||
|
|
||||||
|
@ContributesAndroidInjector abstract fun contributesTreatmentsActivity(): TreatmentsActivity
|
||||||
@ContributesAndroidInjector abstract fun contributesHistoryBrowseActivity(): HistoryBrowseActivity
|
@ContributesAndroidInjector abstract fun contributesHistoryBrowseActivity(): HistoryBrowseActivity
|
||||||
@ContributesAndroidInjector abstract fun contributesLogSettingActivity(): LogSettingActivity
|
@ContributesAndroidInjector abstract fun contributesLogSettingActivity(): LogSettingActivity
|
||||||
@ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity
|
@ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity
|
||||||
|
|
|
@ -31,8 +31,7 @@ import info.nightscout.androidaps.plugins.insulin.InsulinFragment
|
||||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
||||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
|
import info.nightscout.androidaps.activities.fragments.*
|
||||||
import info.nightscout.androidaps.plugins.treatments.fragments.*
|
|
||||||
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
@ -61,7 +60,6 @@ abstract class FragmentsModule {
|
||||||
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
|
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
|
||||||
|
|
||||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesTreatmentsFragment(): TreatmentsFragment
|
|
||||||
@ContributesAndroidInjector abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusCarbsFragment
|
@ContributesAndroidInjector abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusCarbsFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment
|
@ContributesAndroidInjector abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment
|
@ContributesAndroidInjector abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment
|
||||||
|
|
|
@ -27,7 +27,6 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
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.Callback
|
||||||
import info.nightscout.androidaps.queue.CommandQueue
|
import info.nightscout.androidaps.queue.CommandQueue
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.*
|
||||||
|
@ -47,7 +46,6 @@ class CarbsDialog : DialogFragmentWithDate() {
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||||
@Inject lateinit var uel: UserEntryLogger
|
@Inject lateinit var uel: UserEntryLogger
|
||||||
|
|
|
@ -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<GraphView>()
|
|
||||||
private val secondaryGraphsLabel = ArrayList<TextView>()
|
|
||||||
|
|
||||||
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<GraphData> = 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -104,7 +104,8 @@ class ProfileFunctionImplementation @Inject constructor(
|
||||||
timeshift = T.hours(timeShiftInHours.toLong()).msecs(),
|
timeshift = T.hours(timeShiftInHours.toLong()).msecs(),
|
||||||
percentage = percentage,
|
percentage = percentage,
|
||||||
duration = T.mins(durationInMinutes.toLong()).msecs(),
|
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))
|
disposable += repository.runTransactionForResult(InsertOrUpdateProfileSwitch(ps))
|
||||||
.subscribe({ result ->
|
.subscribe({ result ->
|
||||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") }
|
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") }
|
||||||
|
|
|
@ -28,7 +28,7 @@ import info.nightscout.androidaps.events.EventTherapyEventChange
|
||||||
import info.nightscout.androidaps.extensions.toStringMedium
|
import info.nightscout.androidaps.extensions.toStringMedium
|
||||||
import info.nightscout.androidaps.extensions.toStringShort
|
import info.nightscout.androidaps.extensions.toStringShort
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
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.ActivePlugin
|
||||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||||
import info.nightscout.androidaps.interfaces.Config
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
|
|
|
@ -561,9 +561,9 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0)
|
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)
|
val lastChange = sp.getLong(R.string.key_local_profile_last_change, 0)
|
||||||
if (lastChange == 0L) return
|
if (lastChange == 0L) return
|
||||||
localProfilePlugin.createProfileStore()
|
if (lastChange > lastSync) {
|
||||||
val profileJson = localProfilePlugin.profile?.data ?: return
|
val profileJson = localProfilePlugin.profile?.data ?: return
|
||||||
if (lastChange > lastSync)
|
|
||||||
nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
|
nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ class NSClientMbgWorker(
|
||||||
var ret = Result.success()
|
var ret = Result.success()
|
||||||
|
|
||||||
val acceptNSData = sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT
|
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))
|
val mbgArray = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
|
@ -1,46 +1,64 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview
|
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.BarGraphSeries
|
||||||
import com.jjoe64.graphview.series.DataPoint
|
import com.jjoe64.graphview.series.DataPoint
|
||||||
import com.jjoe64.graphview.series.LineGraphSeries
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
|
import info.nightscout.androidaps.database.entities.Bolus
|
||||||
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
||||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||||
import info.nightscout.androidaps.extensions.convertedToPercent
|
import info.nightscout.androidaps.extensions.convertedToPercent
|
||||||
|
import info.nightscout.androidaps.extensions.target
|
||||||
import info.nightscout.androidaps.extensions.toStringFull
|
import info.nightscout.androidaps.extensions.toStringFull
|
||||||
import info.nightscout.androidaps.extensions.toStringShort
|
import info.nightscout.androidaps.extensions.toStringShort
|
||||||
import info.nightscout.androidaps.extensions.valueToUnits
|
import info.nightscout.androidaps.extensions.valueToUnits
|
||||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.FixedLineGraphSeries
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.*
|
||||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
|
||||||
import info.nightscout.androidaps.utils.T
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class OverviewData @Inject constructor(
|
class OverviewData @Inject constructor(
|
||||||
|
private val injector: HasAndroidInjector,
|
||||||
|
private val aapsLogger: AAPSLogger,
|
||||||
private val resourceHelper: ResourceHelper,
|
private val resourceHelper: ResourceHelper,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val activePlugin: ActivePlugin,
|
private val activePlugin: ActivePlugin,
|
||||||
private val defaultValueHelper: DefaultValueHelper,
|
private val defaultValueHelper: DefaultValueHelper,
|
||||||
private val profileFunction: ProfileFunction
|
private val profileFunction: ProfileFunction,
|
||||||
|
private val config: Config,
|
||||||
|
private val 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 {
|
enum class Property {
|
||||||
|
@ -84,7 +102,7 @@ class OverviewData @Inject constructor(
|
||||||
var profileName: String? = null
|
var profileName: String? = null
|
||||||
var profileNameWithRemainingTime: String? = null
|
var profileNameWithRemainingTime: String? = null
|
||||||
|
|
||||||
val profileBackgroudColor: Int
|
val profileBackgroundColor: Int
|
||||||
get() =
|
get() =
|
||||||
profile?.let { profile ->
|
profile?.let { profile ->
|
||||||
if (profile.percentage != 100 || profile.timeshift != 0) resourceHelper.gc(R.color.ribbonWarning)
|
if (profile.percentage != 100 || profile.timeshift != 0) resourceHelper.gc(R.color.ribbonWarning)
|
||||||
|
@ -211,7 +229,7 @@ class OverviewData @Inject constructor(
|
||||||
* TEMP TARGET
|
* TEMP TARGET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var temporarytarget: TemporaryTarget? = null
|
var temporaryTarget: TemporaryTarget? = null
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SENSITIVITY
|
* SENSITIVITY
|
||||||
|
@ -278,4 +296,515 @@ class OverviewData @Inject constructor(
|
||||||
var dsMaxSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
var dsMaxSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
||||||
var dsMinSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
var dsMinSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
@Suppress("SameParameterValue", "UNUSED_PARAMETER")
|
||||||
|
fun prepareBgData(from: String) {
|
||||||
|
// val start = dateUtil.now()
|
||||||
|
maxBgValue = Double.MIN_VALUE
|
||||||
|
bgReadingsArray = repository.compatGetBgReadingsDataFromTime(fromTime, toTime, false).blockingGet()
|
||||||
|
val bgListArray: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
||||||
|
for (bg in bgReadingsArray) {
|
||||||
|
if (bg.timestamp < fromTime || bg.timestamp > toTime) continue
|
||||||
|
if (bg.value > maxBgValue) maxBgValue = bg.value
|
||||||
|
bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, 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<DataPointWithLabelInterface> = java.util.ArrayList()
|
||||||
|
val predictions: MutableList<GlucoseValueDataPoint>? = 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<DataPointWithLabelInterface> = 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<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val tempBasalArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val basalLineArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val absoluteBasalLineArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
var lastLineBasal = 0.0
|
||||||
|
var lastAbsoluteLineBasal = -1.0
|
||||||
|
var lastBaseBasal = 0.0
|
||||||
|
var lastTempBasal = 0.0
|
||||||
|
var time = fromTime
|
||||||
|
while (time < toTime) {
|
||||||
|
val profile = profileFunction.getProfile(time)
|
||||||
|
if (profile == null) {
|
||||||
|
time += 60 * 1000L
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val basalData = iobCobCalculator.getBasalData(profile, time)
|
||||||
|
val baseBasalValue = basalData.basal
|
||||||
|
var absoluteLineValue = baseBasalValue
|
||||||
|
var tempBasalValue = 0.0
|
||||||
|
var basal = 0.0
|
||||||
|
if (basalData.isTempBasalRunning) {
|
||||||
|
tempBasalValue = basalData.tempBasalAbsolute
|
||||||
|
absoluteLineValue = tempBasalValue
|
||||||
|
if (tempBasalValue != lastTempBasal) {
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, lastTempBasal, basalScale))
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, tempBasalValue.also { basal = it }, basalScale))
|
||||||
|
}
|
||||||
|
if (lastBaseBasal != 0.0) {
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, basalScale))
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, 0.0, basalScale))
|
||||||
|
lastBaseBasal = 0.0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (baseBasalValue != lastBaseBasal) {
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, lastBaseBasal, basalScale))
|
||||||
|
baseBasalArray.add(ScaledDataPoint(time, baseBasalValue.also { basal = it }, basalScale))
|
||||||
|
lastBaseBasal = baseBasalValue
|
||||||
|
}
|
||||||
|
if (lastTempBasal != 0.0) {
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, lastTempBasal, basalScale))
|
||||||
|
tempBasalArray.add(ScaledDataPoint(time, 0.0, basalScale))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (baseBasalValue != lastLineBasal) {
|
||||||
|
basalLineArray.add(ScaledDataPoint(time, lastLineBasal, basalScale))
|
||||||
|
basalLineArray.add(ScaledDataPoint(time, baseBasalValue, basalScale))
|
||||||
|
}
|
||||||
|
if (absoluteLineValue != lastAbsoluteLineBasal) {
|
||||||
|
absoluteBasalLineArray.add(ScaledDataPoint(time, lastAbsoluteLineBasal, basalScale))
|
||||||
|
absoluteBasalLineArray.add(ScaledDataPoint(time, basal, basalScale))
|
||||||
|
}
|
||||||
|
lastAbsoluteLineBasal = absoluteLineValue
|
||||||
|
lastLineBasal = baseBasalValue
|
||||||
|
lastTempBasal = tempBasalValue
|
||||||
|
maxBasalValueFound = max(maxBasalValueFound, max(tempBasalValue, baseBasalValue))
|
||||||
|
time += 60 * 1000L
|
||||||
|
}
|
||||||
|
|
||||||
|
// final points
|
||||||
|
basalLineArray.add(ScaledDataPoint(toTime, lastLineBasal, basalScale))
|
||||||
|
baseBasalArray.add(ScaledDataPoint(toTime, lastBaseBasal, basalScale))
|
||||||
|
tempBasalArray.add(ScaledDataPoint(toTime, lastTempBasal, basalScale))
|
||||||
|
absoluteBasalLineArray.add(ScaledDataPoint(toTime, lastAbsoluteLineBasal, basalScale))
|
||||||
|
|
||||||
|
// create series
|
||||||
|
baseBasalGraphSeries = LineGraphSeries(Array(baseBasalArray.size) { i -> baseBasalArray[i] }).also {
|
||||||
|
it.isDrawBackground = true
|
||||||
|
it.backgroundColor = 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<DataPoint> = 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<DataPointWithLabelInterface> = 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<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val absIobArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
maxIobValueFound = Double.MIN_VALUE
|
||||||
|
var lastIob = 0.0
|
||||||
|
var absLastIob = 0.0
|
||||||
|
var time = fromTime
|
||||||
|
|
||||||
|
val minFailOverActiveList: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
||||||
|
val cobArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
maxCobValueFound = Double.MIN_VALUE
|
||||||
|
var lastCob = 0
|
||||||
|
|
||||||
|
val actArrayHist: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val actArrayPrediction: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val now = dateUtil.now().toDouble()
|
||||||
|
maxIAValue = 0.0
|
||||||
|
|
||||||
|
val bgiArrayHist: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val bgiArrayPrediction: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
maxBGIValue = Double.MIN_VALUE
|
||||||
|
|
||||||
|
val devArray: MutableList<OverviewPlugin.DeviationDataPoint> = java.util.ArrayList()
|
||||||
|
maxDevValueFound = Double.MIN_VALUE
|
||||||
|
|
||||||
|
val ratioArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
maxRatioValueFound = 5.0 //even if sens data equals 0 for all the period, minimum scale is between 95% and 105%
|
||||||
|
minRatioValueFound = -5.0
|
||||||
|
|
||||||
|
val dsMaxArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
val dsMinArray: MutableList<ScaledDataPoint> = java.util.ArrayList()
|
||||||
|
maxFromMaxValueFound = Double.MIN_VALUE
|
||||||
|
maxFromMinValueFound = Double.MIN_VALUE
|
||||||
|
|
||||||
|
val adsData = iobCobCalculator.ads.clone()
|
||||||
|
|
||||||
|
while (time <= toTime) {
|
||||||
|
val profile = profileFunction.getProfile(time)
|
||||||
|
if (profile == null) {
|
||||||
|
time += 5 * 60 * 1000L
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// IOB
|
||||||
|
val iob = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile)
|
||||||
|
val baseBasalIob = iobCobCalculator.calculateAbsoluteIobFromBaseBasals(time)
|
||||||
|
val absIob = IobTotal.combine(iob, baseBasalIob)
|
||||||
|
val autosensData = adsData.getAutosensDataAtTime(time)
|
||||||
|
if (abs(lastIob - iob.iob) > 0.02) {
|
||||||
|
if (abs(lastIob - iob.iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
||||||
|
iobArray.add(ScaledDataPoint(time, iob.iob, iobScale))
|
||||||
|
maxIobValueFound = maxOf(maxIobValueFound, abs(iob.iob))
|
||||||
|
lastIob = iob.iob
|
||||||
|
}
|
||||||
|
if (abs(absLastIob - absIob.iob) > 0.02) {
|
||||||
|
if (abs(absLastIob - absIob.iob) > 0.2) absIobArray.add(ScaledDataPoint(time, absLastIob, iobScale))
|
||||||
|
absIobArray.add(ScaledDataPoint(time, absIob.iob, iobScale))
|
||||||
|
maxIobValueFound = maxOf(maxIobValueFound, abs(absIob.iob))
|
||||||
|
absLastIob = absIob.iob
|
||||||
|
}
|
||||||
|
|
||||||
|
// COB
|
||||||
|
if (autosensData != null) {
|
||||||
|
val cob = autosensData.cob.toInt()
|
||||||
|
if (cob != lastCob) {
|
||||||
|
if (autosensData.carbsFromBolus > 0) cobArray.add(ScaledDataPoint(time, lastCob.toDouble(), cobScale))
|
||||||
|
cobArray.add(ScaledDataPoint(time, cob.toDouble(), cobScale))
|
||||||
|
maxCobValueFound = max(maxCobValueFound, cob.toDouble())
|
||||||
|
lastCob = cob
|
||||||
|
}
|
||||||
|
if (autosensData.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<DataPointWithLabelInterface> = java.util.ArrayList()
|
||||||
|
val iobPredictionArray = iobCobCalculator.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
|
||||||
|
for (i in iobPredictionArray) {
|
||||||
|
iobPrediction.add(i.setColor(resourceHelper.gc(R.color.iobPredAS)))
|
||||||
|
maxIobValueFound = max(maxIobValueFound, abs(i.iob))
|
||||||
|
}
|
||||||
|
iobPredictions1Series = PointsWithLabelGraphSeries(Array(iobPrediction.size) { i -> iobPrediction[i] })
|
||||||
|
val iobPrediction2: MutableList<DataPointWithLabelInterface> = java.util.ArrayList()
|
||||||
|
val iobPredictionArray2 = iobCobCalculator.calculateIobArrayForSMB(AutosensResult(), SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
|
||||||
|
for (i in iobPredictionArray2) {
|
||||||
|
iobPrediction2.add(i.setColor(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 <E : DataPointWithLabelInterface> List<E>.filterTimeframe(fromTime: Long, endTime: Long): List<E> =
|
||||||
|
filter { it.x + it.duration >= fromTime && it.x <= endTime }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.pump.common.defs.PumpType
|
||||||
import info.nightscout.androidaps.plugins.source.DexcomPlugin
|
import info.nightscout.androidaps.plugins.source.DexcomPlugin
|
||||||
import info.nightscout.androidaps.plugins.source.XdripPlugin
|
import info.nightscout.androidaps.plugins.source.XdripPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|
||||||
import info.nightscout.androidaps.queue.CommandQueue
|
import info.nightscout.androidaps.queue.CommandQueue
|
||||||
import info.nightscout.androidaps.skins.SkinProvider
|
import info.nightscout.androidaps.skins.SkinProvider
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.*
|
||||||
|
@ -92,7 +91,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
@Inject lateinit var nsDeviceStatus: NSDeviceStatus
|
@Inject lateinit var nsDeviceStatus: NSDeviceStatus
|
||||||
@Inject lateinit var loopPlugin: LoopPlugin
|
@Inject lateinit var loopPlugin: LoopPlugin
|
||||||
@Inject lateinit var activePlugin: ActivePlugin
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
|
||||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||||
@Inject lateinit var dexcomPlugin: DexcomPlugin
|
@Inject lateinit var dexcomPlugin: DexcomPlugin
|
||||||
@Inject lateinit var dexcomMediator: DexcomPlugin.DexcomMediator
|
@Inject lateinit var dexcomMediator: DexcomPlugin.DexcomMediator
|
||||||
|
@ -108,7 +106,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
@Inject lateinit var trendCalculator: TrendCalculator
|
@Inject lateinit var trendCalculator: TrendCalculator
|
||||||
@Inject lateinit var config: Config
|
@Inject lateinit var config: Config
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
|
||||||
@Inject lateinit var uel: UserEntryLogger
|
@Inject lateinit var uel: UserEntryLogger
|
||||||
@Inject lateinit var repository: AppRepository
|
@Inject lateinit var repository: AppRepository
|
||||||
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
@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.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)
|
binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units)
|
||||||
} else {
|
} 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.delta.text = "Δ " + resourceHelper.gs(R.string.notavailable)
|
||||||
binding.infoLayout.avgDelta.text = ""
|
binding.infoLayout.avgDelta.text = ""
|
||||||
binding.infoLayout.longAvgDelta.text = ""
|
binding.infoLayout.longAvgDelta.text = ""
|
||||||
|
@ -640,7 +637,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
OverviewData.Property.PROFILE -> {
|
OverviewData.Property.PROFILE -> {
|
||||||
binding.loopPumpStatusLayout.activeProfile.text = overviewData.profileNameWithRemainingTime
|
binding.loopPumpStatusLayout.activeProfile.text = overviewData.profileNameWithRemainingTime
|
||||||
?: ""
|
?: ""
|
||||||
binding.loopPumpStatusLayout.activeProfile.setBackgroundColor(overviewData.profileBackgroudColor)
|
binding.loopPumpStatusLayout.activeProfile.setBackgroundColor(overviewData.profileBackgroundColor)
|
||||||
binding.loopPumpStatusLayout.activeProfile.setTextColor(overviewData.profileTextColor)
|
binding.loopPumpStatusLayout.activeProfile.setTextColor(overviewData.profileTextColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,7 +702,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
|
|
||||||
OverviewData.Property.TEMPORARY_TARGET -> {
|
OverviewData.Property.TEMPORARY_TARGET -> {
|
||||||
// temp target
|
// temp target
|
||||||
val tempTarget = overviewData.temporarytarget
|
val tempTarget = overviewData.temporaryTarget
|
||||||
if (tempTarget != null) {
|
if (tempTarget != null) {
|
||||||
binding.loopPumpStatusLayout.tempTarget.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning))
|
binding.loopPumpStatusLayout.tempTarget.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning))
|
||||||
binding.loopPumpStatusLayout.tempTarget.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning))
|
binding.loopPumpStatusLayout.tempTarget.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning))
|
||||||
|
@ -730,7 +727,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
|
|
||||||
OverviewData.Property.GRAPH -> {
|
OverviewData.Property.GRAPH -> {
|
||||||
val graphData = GraphData(injector, binding.graphsLayout.bgGraph)
|
val graphData = GraphData(injector, binding.graphsLayout.bgGraph, overviewData)
|
||||||
val menuChartSettings = overviewMenus.setting
|
val menuChartSettings = overviewMenus.setting
|
||||||
graphData.addInRangeArea(overviewData.fromTime, overviewData.endTime, defaultValueHelper.determineLowLine(), defaultValueHelper.determineHighLine())
|
graphData.addInRangeArea(overviewData.fromTime, overviewData.endTime, defaultValueHelper.determineLowLine(), defaultValueHelper.determineHighLine())
|
||||||
graphData.addBgReadings(menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
|
graphData.addBgReadings(menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
|
||||||
|
@ -755,7 +752,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
|
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
for (g in 0 until min(secondaryGraphs.size, menuChartSettings.size + 1)) {
|
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 useABSForScale = false
|
||||||
var useIobForScale = false
|
var useIobForScale = false
|
||||||
var useCobForScale = false
|
var useCobForScale = false
|
||||||
|
|
|
@ -1,85 +1,68 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview
|
package info.nightscout.androidaps.plugins.general.overview
|
||||||
|
|
||||||
import android.graphics.DashPathEffect
|
|
||||||
import android.graphics.Paint
|
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.SwitchPreference
|
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 dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.database.ValueWrapper
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
import info.nightscout.androidaps.database.entities.Bolus
|
|
||||||
import info.nightscout.androidaps.events.*
|
import info.nightscout.androidaps.events.*
|
||||||
import info.nightscout.androidaps.extensions.*
|
import info.nightscout.androidaps.extensions.*
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventLoopInvoked
|
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.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.EventDismissNotification
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
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.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.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.EventBucketedDataCreated
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
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.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxkotlin.plusAssign
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.ceil
|
|
||||||
import kotlin.math.max
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class OverviewPlugin @Inject constructor(
|
class OverviewPlugin @Inject constructor(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
private val notificationStore: NotificationStore,
|
private val notificationStore: NotificationStore,
|
||||||
private val fabricPrivacy: FabricPrivacy,
|
private val fabricPrivacy: FabricPrivacy,
|
||||||
private val rxBus: RxBusWrapper,
|
private val rxBus: RxBusWrapper,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
private val aapsSchedulers: AapsSchedulers,
|
private val aapsSchedulers: AapsSchedulers,
|
||||||
resourceHelper: ResourceHelper,
|
resourceHelper: ResourceHelper,
|
||||||
private val config: Config,
|
private val config: Config,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
private val translator: Translator,
|
private val translator: Translator,
|
||||||
// private val profiler: Profiler,
|
// private val profiler: Profiler,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val iobCobCalculator: IobCobCalculator,
|
private val iobCobCalculator: IobCobCalculator,
|
||||||
private val repository: AppRepository,
|
private val repository: AppRepository,
|
||||||
private val defaultValueHelper: DefaultValueHelper,
|
private val overviewData: OverviewData,
|
||||||
private val loopPlugin: LoopPlugin,
|
private val overviewMenus: OverviewMenus
|
||||||
private val activePlugin: ActivePlugin,
|
|
||||||
private val nsDeviceStatus: NSDeviceStatus,
|
|
||||||
private val overviewData: OverviewData,
|
|
||||||
private val overviewMenus: OverviewMenus
|
|
||||||
) : PluginBase(PluginDescription()
|
) : PluginBase(PluginDescription()
|
||||||
.mainType(PluginType.GENERAL)
|
.mainType(PluginType.GENERAL)
|
||||||
.fragmentClass(OverviewFragment::class.qualifiedName)
|
.fragmentClass(OverviewFragment::class.qualifiedName)
|
||||||
.alwaysVisible(true)
|
.alwaysVisible(true)
|
||||||
.alwaysEnabled(true)
|
.alwaysEnabled(true)
|
||||||
.pluginIcon(R.drawable.ic_home)
|
.pluginIcon(R.drawable.ic_home)
|
||||||
.pluginName(R.string.overview)
|
.pluginName(R.string.overview)
|
||||||
.shortName(R.string.overview_shortname)
|
.shortName(R.string.overview_shortname)
|
||||||
.preferencesId(R.xml.pref_overview)
|
.preferencesId(R.xml.pref_overview)
|
||||||
.description(R.string.description_overview),
|
.description(R.string.description_overview),
|
||||||
aapsLogger, resourceHelper, injector
|
aapsLogger, resourceHelper, injector
|
||||||
), Overview {
|
), Overview {
|
||||||
|
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
@ -95,74 +78,76 @@ class OverviewPlugin @Inject constructor(
|
||||||
|
|
||||||
notificationStore.createNotificationChannel()
|
notificationStore.createNotificationChannel()
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNewNotification::class.java)
|
.toObservable(EventNewNotification::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ n ->
|
.subscribe({ n ->
|
||||||
if (notificationStore.add(n.notification))
|
if (notificationStore.add(n.notification))
|
||||||
rxBus.send(EventRefreshOverview("EventNewNotification"))
|
rxBus.send(EventRefreshOverview("EventNewNotification"))
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventDismissNotification::class.java)
|
.toObservable(EventDismissNotification::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ n ->
|
.subscribe({ n ->
|
||||||
if (notificationStore.remove(n.id))
|
if (notificationStore.remove(n.id))
|
||||||
rxBus.send(EventRefreshOverview("EventDismissNotification"))
|
rxBus.send(EventRefreshOverview("EventDismissNotification"))
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventIobCalculationProgress::class.java)
|
.toObservable(EventIobCalculationProgress::class.java)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ overviewData.calcProgress = it.progress; overviewBus.send(EventUpdateOverview("EventIobCalculationProgress", OverviewData.Property.CALC_PROGRESS)) }, fabricPrivacy::logException)
|
.subscribe({ overviewData.calcProgress = it.progress; overviewBus.send(EventUpdateOverview("EventIobCalculationProgress", OverviewData.Property.CALC_PROGRESS)) }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventTempBasalChange::class.java)
|
.toObservable(EventTempBasalChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ loadTemporaryBasal("EventTempBasalChange") }, fabricPrivacy::logException)
|
.subscribe({ loadTemporaryBasal("EventTempBasalChange") }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventExtendedBolusChange::class.java)
|
.toObservable(EventExtendedBolusChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ loadExtendedBolus("EventExtendedBolusChange") }, fabricPrivacy::logException)
|
.subscribe({ loadExtendedBolus("EventExtendedBolusChange") }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNewBG::class.java)
|
.toObservable(EventNewBG::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ loadBg("EventNewBG") }, fabricPrivacy::logException)
|
.subscribe({ loadBg("EventNewBG") }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventTempTargetChange::class.java)
|
.toObservable(EventTempTargetChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ loadTemporaryTarget("EventTempTargetChange") }, fabricPrivacy::logException)
|
.subscribe({ loadTemporaryTarget("EventTempTargetChange") }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventTreatmentChange::class.java)
|
.toObservable(EventTreatmentChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
loadIobCobResults("EventTreatmentChange")
|
loadIobCobResults("EventTreatmentChange")
|
||||||
prepareTreatmentsData("EventTreatmentChange")
|
overviewData.prepareTreatmentsData("EventTreatmentChange")
|
||||||
overviewBus.send(EventUpdateOverview("EventTreatmentChange", OverviewData.Property.GRAPH))
|
overviewBus.send(EventUpdateOverview("EventTreatmentChange", OverviewData.Property.GRAPH))
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventTherapyEventChange::class.java)
|
.toObservable(EventTherapyEventChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
prepareTreatmentsData("EventTherapyEventChange")
|
overviewData.prepareTreatmentsData("EventTherapyEventChange")
|
||||||
overviewBus.send(EventUpdateOverview("EventTherapyEventChange", OverviewData.Property.GRAPH))
|
overviewBus.send(EventUpdateOverview("EventTherapyEventChange", OverviewData.Property.GRAPH))
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventBucketedDataCreated::class.java)
|
.toObservable(EventBucketedDataCreated::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
prepareBucketedData("EventBucketedDataCreated")
|
overviewData.prepareBucketedData("EventBucketedDataCreated")
|
||||||
prepareBgData("EventBucketedDataCreated")
|
overviewData.prepareBgData("EventBucketedDataCreated")
|
||||||
overviewBus.send(EventUpdateOverview("EventBucketedDataCreated", OverviewData.Property.GRAPH))
|
overviewBus.send(EventUpdateOverview("EventBucketedDataCreated", OverviewData.Property.GRAPH))
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventLoopInvoked::class.java)
|
.toObservable(EventLoopInvoked::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ preparePredictions("EventLoopInvoked") }, fabricPrivacy::logException)
|
.subscribe({ overviewData.preparePredictions("EventLoopInvoked") }, fabricPrivacy::logException)
|
||||||
disposable.add(rxBus
|
disposable.add(rxBus
|
||||||
.toObservable(EventProfileSwitchChanged::class.java)
|
.toObservable(EventProfileSwitchChanged::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ loadProfile("EventProfileSwitchChanged") }, fabricPrivacy::logException))
|
.subscribe({ loadProfile("EventProfileSwitchChanged") }, fabricPrivacy::logException))
|
||||||
disposable.add(rxBus
|
disposable.add(rxBus
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ refreshLoop("EventAutosensCalculationFinished") }, fabricPrivacy::logException))
|
.subscribe({
|
||||||
|
if (it.cause !is EventCustomCalculationFinished) refreshLoop("EventAutosensCalculationFinished")
|
||||||
|
}, fabricPrivacy::logException))
|
||||||
|
|
||||||
Thread { loadAll("onResume") }.start()
|
Thread { loadAll("onResume") }.start()
|
||||||
}
|
}
|
||||||
|
@ -187,59 +172,60 @@ class OverviewPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configuration(): JSONObject =
|
override fun configuration(): JSONObject =
|
||||||
JSONObject()
|
JSONObject()
|
||||||
.putString(R.string.key_quickwizard, sp, resourceHelper)
|
.putString(R.string.key_quickwizard, sp, resourceHelper)
|
||||||
.putInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
|
.putInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
|
.putDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
|
||||||
.putInt(R.string.key_activity_duration, sp, resourceHelper)
|
.putInt(R.string.key_activity_duration, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_activity_target, sp, resourceHelper)
|
.putDouble(R.string.key_activity_target, sp, resourceHelper)
|
||||||
.putInt(R.string.key_hypo_duration, sp, resourceHelper)
|
.putInt(R.string.key_hypo_duration, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_hypo_target, sp, resourceHelper)
|
.putDouble(R.string.key_hypo_target, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_low_mark, sp, resourceHelper)
|
.putDouble(R.string.key_low_mark, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_high_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_warning, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_statuslights_cage_critical, 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_warning, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_statuslights_iage_critical, 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_warning, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_statuslights_sage_critical, 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_warning, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_statuslights_sbat_critical, 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_warning, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_statuslights_bage_critical, 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_warning, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_statuslights_res_critical, 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_warning, sp, resourceHelper)
|
||||||
.putDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
|
.putDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
|
||||||
|
|
||||||
override fun applyConfiguration(configuration: JSONObject) {
|
override fun applyConfiguration(configuration: JSONObject) {
|
||||||
configuration
|
configuration
|
||||||
.storeString(R.string.key_quickwizard, sp, resourceHelper)
|
.storeString(R.string.key_quickwizard, sp, resourceHelper)
|
||||||
.storeInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
|
.storeInt(R.string.key_eatingsoon_duration, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
|
.storeDouble(R.string.key_eatingsoon_target, sp, resourceHelper)
|
||||||
.storeInt(R.string.key_activity_duration, sp, resourceHelper)
|
.storeInt(R.string.key_activity_duration, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_activity_target, sp, resourceHelper)
|
.storeDouble(R.string.key_activity_target, sp, resourceHelper)
|
||||||
.storeInt(R.string.key_hypo_duration, sp, resourceHelper)
|
.storeInt(R.string.key_hypo_duration, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_hypo_target, sp, resourceHelper)
|
.storeDouble(R.string.key_hypo_target, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_low_mark, sp, resourceHelper)
|
.storeDouble(R.string.key_low_mark, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_high_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_warning, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_statuslights_cage_critical, 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_warning, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_statuslights_iage_critical, 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_warning, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_statuslights_sage_critical, 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_warning, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_statuslights_sbat_critical, 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_warning, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_statuslights_bage_critical, 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_warning, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_statuslights_res_critical, 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_warning, sp, resourceHelper)
|
||||||
.storeDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
|
.storeDouble(R.string.key_statuslights_bat_critical, sp, resourceHelper)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Volatile var runningRefresh = false
|
@Volatile
|
||||||
|
var runningRefresh = false
|
||||||
override fun refreshLoop(from: String) {
|
override fun refreshLoop(from: String) {
|
||||||
if (runningRefresh) return
|
if (runningRefresh) return
|
||||||
runningRefresh = true
|
runningRefresh = true
|
||||||
|
@ -252,11 +238,11 @@ class OverviewPlugin @Inject constructor(
|
||||||
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_TARGET))
|
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_TARGET))
|
||||||
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.SENSITIVITY))
|
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.SENSITIVITY))
|
||||||
loadAsData(from)
|
loadAsData(from)
|
||||||
preparePredictions(from)
|
overviewData.preparePredictions(from)
|
||||||
prepareBasalData(from)
|
overviewData.prepareBasalData(from)
|
||||||
prepareTemporaryTargetData(from)
|
overviewData.prepareTemporaryTargetData(from)
|
||||||
prepareTreatmentsData(from)
|
overviewData.prepareTreatmentsData(from)
|
||||||
prepareIobAutosensData(from)
|
overviewData.prepareIobAutosensData(from)
|
||||||
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.GRAPH))
|
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.GRAPH))
|
||||||
aapsLogger.debug(LTag.UI, "refreshLoop finished")
|
aapsLogger.debug(LTag.UI, "refreshLoop finished")
|
||||||
runningRefresh = false
|
runningRefresh = false
|
||||||
|
@ -271,9 +257,9 @@ class OverviewPlugin @Inject constructor(
|
||||||
loadTemporaryTarget(from)
|
loadTemporaryTarget(from)
|
||||||
loadIobCobResults(from)
|
loadIobCobResults(from)
|
||||||
loadAsData(from)
|
loadAsData(from)
|
||||||
prepareBasalData(from)
|
overviewData.prepareBasalData(from)
|
||||||
prepareTemporaryTargetData(from)
|
overviewData.prepareTemporaryTargetData(from)
|
||||||
prepareTreatmentsData(from)
|
overviewData.prepareTreatmentsData(from)
|
||||||
// prepareIobAutosensData(from)
|
// prepareIobAutosensData(from)
|
||||||
// preparePredictions(from)
|
// preparePredictions(from)
|
||||||
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.GRAPH))
|
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.GRAPH))
|
||||||
|
@ -299,8 +285,8 @@ class OverviewPlugin @Inject constructor(
|
||||||
|
|
||||||
private fun loadTemporaryTarget(from: String) {
|
private fun loadTemporaryTarget(from: String) {
|
||||||
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
||||||
if (tempTarget is ValueWrapper.Existing) overviewData.temporarytarget = tempTarget.value
|
if (tempTarget is ValueWrapper.Existing) overviewData.temporaryTarget = tempTarget.value
|
||||||
else overviewData.temporarytarget = null
|
else overviewData.temporaryTarget = null
|
||||||
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_TARGET))
|
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.TEMPORARY_TARGET))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,514 +312,4 @@ class OverviewPlugin @Inject constructor(
|
||||||
overviewBus.send(EventUpdateOverview(from, OverviewData.Property.IOB_COB))
|
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<DataPointWithLabelInterface> = 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<DataPointWithLabelInterface> = ArrayList()
|
|
||||||
val predictions: MutableList<GlucoseValueDataPoint>? = 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<DataPointWithLabelInterface> = 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<ScaledDataPoint> = ArrayList()
|
|
||||||
val tempBasalArray: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
val basalLineArray: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
val absoluteBasalLineArray: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
var lastLineBasal = 0.0
|
|
||||||
var lastAbsoluteLineBasal = -1.0
|
|
||||||
var lastBaseBasal = 0.0
|
|
||||||
var lastTempBasal = 0.0
|
|
||||||
var time = 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<DataPoint> = 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<DataPointWithLabelInterface> = 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<ScaledDataPoint> = ArrayList()
|
|
||||||
val absIobArray: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
overviewData.maxIobValueFound = Double.MIN_VALUE
|
|
||||||
var lastIob = 0.0
|
|
||||||
var absLastIob = 0.0
|
|
||||||
var time = overviewData.fromTime
|
|
||||||
|
|
||||||
val minFailOverActiveList: MutableList<DataPointWithLabelInterface> = ArrayList()
|
|
||||||
val cobArray: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
overviewData.maxCobValueFound = Double.MIN_VALUE
|
|
||||||
var lastCob = 0
|
|
||||||
|
|
||||||
val actArrayHist: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
val actArrayPrediction: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
val now = dateUtil.now().toDouble()
|
|
||||||
overviewData.maxIAValue = 0.0
|
|
||||||
|
|
||||||
val bgiArrayHist: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
val bgiArrayPrediction: MutableList<ScaledDataPoint> = ArrayList()
|
|
||||||
overviewData.maxBGIValue = Double.MIN_VALUE
|
|
||||||
|
|
||||||
val devArray: MutableList<DeviationDataPoint> = ArrayList()
|
|
||||||
overviewData.maxDevValueFound = Double.MIN_VALUE
|
|
||||||
|
|
||||||
val ratioArray: MutableList<ScaledDataPoint> = 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<ScaledDataPoint> = ArrayList()
|
|
||||||
val dsMinArray: MutableList<ScaledDataPoint> = 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<DataPointWithLabelInterface> = 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<DataPointWithLabelInterface> = 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 <E : DataPointWithLabelInterface> List<E>.filterTimeframe(fromTime: Long, endTime: Long): List<E> =
|
|
||||||
filter { it.x + it.duration >= fromTime && it.x <= endTime }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,16 +27,16 @@ import kotlin.math.max
|
||||||
|
|
||||||
class GraphData(
|
class GraphData(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
private val graph: GraphView
|
private val graph: GraphView,
|
||||||
|
private val overviewData: OverviewData
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
@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 var minY = Double.MAX_VALUE
|
||||||
private val units: GlucoseUnit
|
private val units: GlucoseUnit
|
||||||
private val series: MutableList<Series<*>> = ArrayList()
|
private val series: MutableList<Series<*>> = ArrayList()
|
||||||
|
@ -214,7 +214,7 @@ class GraphData(
|
||||||
graph.gridLabelRenderer.numHorizontalLabels = 7 // only 7 because of the space
|
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() {
|
fun performUpdate() {
|
||||||
// clear old data
|
// clear old data
|
||||||
|
|
|
@ -99,7 +99,7 @@ class IobCobOref1Thread internal constructor(
|
||||||
// start from oldest to be able sub cob
|
// start from oldest to be able sub cob
|
||||||
for (i in bucketedData.size - 4 downTo 0) {
|
for (i in bucketedData.size - 4 downTo 0) {
|
||||||
val progress = i.toString() + if (buildHelper.isDev()) " ($from)" else ""
|
val progress = i.toString() + if (buildHelper.isDev()) " ($from)" else ""
|
||||||
rxBus.send(EventIobCalculationProgress(progress))
|
rxBus.send(EventIobCalculationProgress(progress, cause))
|
||||||
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
|
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
|
||||||
iobCobCalculatorPlugin.stopCalculationTrigger = false
|
iobCobCalculatorPlugin.stopCalculationTrigger = false
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from")
|
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from")
|
||||||
|
@ -325,7 +325,7 @@ class IobCobOref1Thread internal constructor(
|
||||||
}.start()
|
}.start()
|
||||||
} finally {
|
} finally {
|
||||||
mWakeLock?.release()
|
mWakeLock?.release()
|
||||||
rxBus.send(EventIobCalculationProgress(""))
|
rxBus.send(EventIobCalculationProgress("", cause))
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
||||||
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
|
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ class IobCobThread @Inject internal constructor(
|
||||||
// start from oldest to be able sub cob
|
// start from oldest to be able sub cob
|
||||||
for (i in bucketedData.size - 4 downTo 0) {
|
for (i in bucketedData.size - 4 downTo 0) {
|
||||||
val progress = i.toString() + if (buildHelper.isDev()) " ($from)" else ""
|
val progress = i.toString() + if (buildHelper.isDev()) " ($from)" else ""
|
||||||
rxBus.send(EventIobCalculationProgress(progress))
|
rxBus.send(EventIobCalculationProgress(progress, cause))
|
||||||
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
|
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
|
||||||
iobCobCalculatorPlugin.stopCalculationTrigger = false
|
iobCobCalculatorPlugin.stopCalculationTrigger = false
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from")
|
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): $from")
|
||||||
|
@ -272,7 +272,7 @@ class IobCobThread @Inject internal constructor(
|
||||||
}.start()
|
}.start()
|
||||||
} finally {
|
} finally {
|
||||||
mWakeLock?.release()
|
mWakeLock?.release()
|
||||||
rxBus.send(EventIobCalculationProgress(""))
|
rxBus.send(EventIobCalculationProgress("", cause))
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
||||||
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
|
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,4 @@ package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
import info.nightscout.androidaps.events.Event
|
||||||
|
|
||||||
class EventIobCalculationProgress(var progress: String) : Event()
|
class EventIobCalculationProgress(val progress: String, val cause: Event?) : Event()
|
|
@ -70,7 +70,7 @@ class LocalProfileFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sumLabel(): String {
|
private fun sumLabel(): String {
|
||||||
val profile = localProfilePlugin.createProfileStore().getDefaultProfile()
|
val profile = localProfilePlugin.profile?.getDefaultProfile()
|
||||||
val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0
|
val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0
|
||||||
return " ∑" + DecimalFormatter.to2Decimal(sum) + resourceHelper.gs(R.string.insulin_unit_shortname)
|
return " ∑" + DecimalFormatter.to2Decimal(sum) + resourceHelper.gs(R.string.insulin_unit_shortname)
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ class LocalProfilePlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
sp.putInt(Constants.LOCAL_PROFILE + "_profiles", numOfProfiles)
|
sp.putInt(Constants.LOCAL_PROFILE + "_profiles", numOfProfiles)
|
||||||
|
|
||||||
|
sp.putLong(R.string.key_local_profile_last_change, dateUtil.now())
|
||||||
createAndStoreConvertedProfile()
|
createAndStoreConvertedProfile()
|
||||||
isEdited = false
|
isEdited = false
|
||||||
aapsLogger.debug(LTag.PROFILE, "Storing settings: " + rawProfile?.data.toString())
|
aapsLogger.debug(LTag.PROFILE, "Storing settings: " + rawProfile?.data.toString())
|
||||||
|
@ -148,12 +149,9 @@ class LocalProfilePlugin @Inject constructor(
|
||||||
val name = it.name ?: "."
|
val name = it.name ?: "."
|
||||||
if (name.contains(".")) namesOK = false
|
if (name.contains(".")) namesOK = false
|
||||||
}
|
}
|
||||||
if (namesOK)
|
if (!namesOK) activity?.let {
|
||||||
sp.putLong(R.string.key_local_profile_last_change, dateUtil.now())
|
OKDialog.show(it, "", resourceHelper.gs(R.string.profilenamecontainsdot))
|
||||||
else
|
}
|
||||||
activity?.let {
|
|
||||||
OKDialog.show(it, "", resourceHelper.gs(R.string.profilenamecontainsdot))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -372,7 +370,8 @@ class LocalProfilePlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (numOfProfiles > 0) json.put("defaultProfile", currentProfile()?.name)
|
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)
|
json.put("store", store)
|
||||||
} catch (e: JSONException) {
|
} catch (e: JSONException) {
|
||||||
aapsLogger.error("Unhandled exception", e)
|
aapsLogger.error("Unhandled exception", e)
|
||||||
|
@ -412,11 +411,19 @@ class LocalProfilePlugin @Inject constructor(
|
||||||
val profileJson = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
|
val profileJson = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
if (sp.getBoolean(R.string.key_ns_receive_profile_store, false) || config.NSCLIENT) {
|
if (sp.getBoolean(R.string.key_ns_receive_profile_store, false) || config.NSCLIENT) {
|
||||||
localProfilePlugin.loadFromStore(ProfileStore(injector, profileJson, dateUtil))
|
val store = ProfileStore(injector, profileJson, dateUtil)
|
||||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
|
val startDate = store.getStartDate()
|
||||||
return Result.success(workDataOf("Data" to profileJson.toString().substring(0..min(5000, profileJson.length()))))
|
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"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class DexcomPlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
var ret = Result.success()
|
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))
|
val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -69,7 +69,7 @@ class EversensePlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
var ret = Result.success()
|
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))
|
val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
if (bundle.containsKey("currentCalibrationPhase")) aapsLogger.debug(LTag.BGSOURCE, "currentCalibrationPhase: " + bundle.getString("currentCalibrationPhase"))
|
if (bundle.containsKey("currentCalibrationPhase")) aapsLogger.debug(LTag.BGSOURCE, "currentCalibrationPhase: " + bundle.getString("currentCalibrationPhase"))
|
||||||
|
|
|
@ -56,7 +56,7 @@ class GlimpPlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
var ret = Result.success()
|
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}")
|
aapsLogger.debug(LTag.BGSOURCE, "Received Glimp Data: $inputData}")
|
||||||
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
|
|
|
@ -115,7 +115,7 @@ class NSClientSourcePlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
var ret = Result.success()
|
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))
|
val sgvs = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
|
@ -60,7 +60,7 @@ class PoctechPlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
var ret = Result.success()
|
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")
|
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $inputData")
|
||||||
try {
|
try {
|
||||||
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
|
|
|
@ -59,7 +59,7 @@ class TomatoPlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
var ret = Result.success()
|
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<CgmSourceTransaction.TransactionGlucoseValue>()
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
timestamp = inputData.getLong("com.fanqies.tomatofn.Extras.Time", 0),
|
timestamp = inputData.getLong("com.fanqies.tomatofn.Extras.Time", 0),
|
||||||
|
|
|
@ -73,7 +73,7 @@ class XdripPlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
var ret = Result.success()
|
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))
|
val bundle = dataWorker.pickupBundle(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
||||||
) {
|
) {
|
||||||
super(new PluginDescription()
|
super(new PluginDescription()
|
||||||
.mainType(PluginType.TREATMENT)
|
.mainType(PluginType.TREATMENT)
|
||||||
.fragmentClass(TreatmentsFragment.class.getName())
|
|
||||||
.pluginIcon(R.drawable.ic_treatments)
|
.pluginIcon(R.drawable.ic_treatments)
|
||||||
.pluginName(R.string.treatments)
|
.pluginName(R.string.treatments)
|
||||||
.shortName(R.string.treatments_shortname)
|
.shortName(R.string.treatments_shortname)
|
||||||
|
|
|
@ -566,11 +566,12 @@ open class CommandQueue @Inject constructor(
|
||||||
return HtmlHelper.fromHtml(s)
|
return HtmlHelper.fromHtml(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isThisProfileSet(profile: Profile): Boolean {
|
override fun isThisProfileSet(requestedProfile: Profile): Boolean {
|
||||||
val result = activePlugin.activePump.isThisProfileSet(profile)
|
val runningProfile = profileFunction.getProfile() ?: return false
|
||||||
|
val result = activePlugin.activePump.isThisProfileSet(requestedProfile) && requestedProfile.isEqual(runningProfile)
|
||||||
if (!result) {
|
if (!result) {
|
||||||
aapsLogger.debug(LTag.PUMPQUEUE, "Current profile: ${profileFunction.getProfile()}")
|
aapsLogger.debug(LTag.PUMPQUEUE, "Current profile: ${profileFunction.getProfile()}")
|
||||||
aapsLogger.debug(LTag.PUMPQUEUE, "New profile: $profile")
|
aapsLogger.debug(LTag.PUMPQUEUE, "New profile: $requestedProfile")
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,18 +119,18 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
||||||
private fun checkPump() {
|
private fun checkPump() {
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
val ps = profileFunction.getRequestedProfile() ?: return
|
val ps = profileFunction.getRequestedProfile() ?: return
|
||||||
val profile = ProfileSealed.PS(ps)
|
val requestedProfile = ProfileSealed.PS(ps)
|
||||||
|
val runningProfile = profileFunction.getProfile()
|
||||||
val lastConnection = pump.lastDataTime()
|
val lastConnection = pump.lastDataTime()
|
||||||
val isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis()
|
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))
|
aapsLogger.debug(LTag.CORE, "Last connection: " + dateUtil.dateAndTimeString(lastConnection))
|
||||||
// sometimes keep alive broadcast stops
|
// sometimes keep alive broadcast stops
|
||||||
// as as workaround test if readStatus was requested before an alarm is generated
|
// as as workaround test if readStatus was requested before an alarm is generated
|
||||||
if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) {
|
if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) {
|
||||||
localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loopPlugin.isDisconnected)
|
localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loopPlugin.isDisconnected)
|
||||||
}
|
}
|
||||||
if (!pump.isThisProfileSet(profile) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)
|
if (runningProfile == null || ((!pump.isThisProfileSet(requestedProfile) || !requestedProfile.isEqual(runningProfile)) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE))) {
|
||||||
|| profileFunction.getProfile() == null) {
|
|
||||||
rxBus.send(EventProfileSwitchChanged())
|
rxBus.send(EventProfileSwitchChanged())
|
||||||
} else if (isStatusOutdated && !pump.isBusy()) {
|
} else if (isStatusOutdated && !pump.isBusy()) {
|
||||||
lastReadStatus = System.currentTimeMillis()
|
lastReadStatus = System.currentTimeMillis()
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity">
|
tools:context="info.nightscout.androidaps.activities.HistoryBrowseActivity">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
android:layout_weight="1">
|
android:layout_weight="1">
|
||||||
|
|
||||||
<com.jjoe64.graphview.GraphView
|
<com.jjoe64.graphview.GraphView
|
||||||
android:id="@+id/bggraph"
|
android:id="@+id/bg_graph"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
|
|
@ -239,7 +239,7 @@
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:orientation="vertical" />
|
android:orientation="vertical" />
|
||||||
|
|
||||||
<info.nightscout.androidaps.plugins.treatments.fragments.ProfileGraph
|
<info.nightscout.androidaps.utils.ui.ProfileGraph
|
||||||
android:id="@+id/basal_graph"
|
android:id="@+id/basal_graph"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="100dip"
|
android:layout_height="100dip"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context=".plugins.treatments.fragments.TreatmentsBolusCarbsFragment">
|
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsBolusCarbsFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsCareportalFragment">
|
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsCareportalFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context=".plugins.treatments.fragments.TreatmentsExtendedBolusesFragment">
|
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context=".plugins.treatments.TreatmentsFragment">
|
tools:context="info.nightscout.androidaps.activities.TreatmentsActivity">
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.flexbox.FlexboxLayout
|
<com.google.android.flexbox.FlexboxLayout
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsProfileSwitchFragment">
|
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsTemporaryBasalsFragment">
|
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment">
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsTempTargetFragment">
|
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context=".plugins.treatments.fragments.TreatmentsUserEntryFragment">
|
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsUserEntryFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
android:id="@+id/nav_plugin_preferences"
|
android:id="@+id/nav_plugin_preferences"
|
||||||
app:showAsAction="never"
|
app:showAsAction="never"
|
||||||
android:title="@string/nav_plugin_preferences" />
|
android:title="@string/nav_plugin_preferences" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_treatments"
|
||||||
|
app:showAsAction="never"
|
||||||
|
android:title="@string/treatments" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_historybrowser"
|
android:id="@+id/nav_historybrowser"
|
||||||
app:showAsAction="never"
|
app:showAsAction="never"
|
||||||
|
|
|
@ -28,8 +28,6 @@ import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||||
import info.nightscout.androidaps.plugins.source.GlimpPlugin
|
import info.nightscout.androidaps.plugins.source.GlimpPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentService
|
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|
||||||
import info.nightscout.androidaps.utils.HardLimits
|
import info.nightscout.androidaps.utils.HardLimits
|
||||||
import info.nightscout.androidaps.utils.Profiler
|
import info.nightscout.androidaps.utils.Profiler
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
|
@ -51,7 +49,7 @@ import java.util.*
|
||||||
@RunWith(PowerMockRunner::class)
|
@RunWith(PowerMockRunner::class)
|
||||||
@PrepareForTest(
|
@PrepareForTest(
|
||||||
ConstraintChecker::class, SP::class, Context::class,
|
ConstraintChecker::class, SP::class, Context::class,
|
||||||
OpenAPSAMAPlugin::class, OpenAPSSMBPlugin::class, TreatmentsPlugin::class, TreatmentService::class,
|
OpenAPSAMAPlugin::class, OpenAPSSMBPlugin::class,
|
||||||
VirtualPumpPlugin::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class, GlimpPlugin::class, Profiler::class,
|
VirtualPumpPlugin::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class, GlimpPlugin::class, Profiler::class,
|
||||||
UserEntryLogger::class, LoggerUtils::class, AppRepository::class, InsightDatabaseDao::class)
|
UserEntryLogger::class, LoggerUtils::class, AppRepository::class, InsightDatabaseDao::class)
|
||||||
class ConstraintsCheckerTest : TestBaseWithProfile() {
|
class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
|
|
|
@ -14,7 +14,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration
|
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|
||||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
@ -41,7 +40,6 @@ class LoopPluginTest : TestBase() {
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
@Mock lateinit var commandQueue: CommandQueueProvider
|
@Mock lateinit var commandQueue: CommandQueueProvider
|
||||||
@Mock lateinit var activePlugin: ActivePlugin
|
@Mock lateinit var activePlugin: ActivePlugin
|
||||||
@Mock lateinit var treatmentsPlugin: TreatmentsPlugin
|
|
||||||
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
||||||
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
||||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||||
|
|
|
@ -20,7 +20,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
|
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|
||||||
import info.nightscout.androidaps.queue.commands.*
|
import info.nightscout.androidaps.queue.commands.*
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
@ -45,7 +44,7 @@ import java.util.*
|
||||||
@RunWith(PowerMockRunner::class)
|
@RunWith(PowerMockRunner::class)
|
||||||
@PrepareForTest(
|
@PrepareForTest(
|
||||||
ConstraintChecker::class, VirtualPumpPlugin::class, ToastUtils::class, Context::class,
|
ConstraintChecker::class, VirtualPumpPlugin::class, ToastUtils::class, Context::class,
|
||||||
TreatmentsPlugin::class, FabricPrivacy::class, LoggerUtils::class, PowerManager::class,
|
FabricPrivacy::class, LoggerUtils::class, PowerManager::class,
|
||||||
AppRepository::class)
|
AppRepository::class)
|
||||||
class CommandQueueTest : TestBaseWithProfile() {
|
class CommandQueueTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ import info.nightscout.androidaps.interfaces.PumpSync
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
|
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|
||||||
import info.nightscout.androidaps.queue.commands.Command
|
import info.nightscout.androidaps.queue.commands.Command
|
||||||
import info.nightscout.androidaps.queue.commands.CommandTempBasalAbsolute
|
import info.nightscout.androidaps.queue.commands.CommandTempBasalAbsolute
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
@ -34,7 +33,7 @@ import org.powermock.modules.junit4.PowerMockRunner
|
||||||
@RunWith(PowerMockRunner::class)
|
@RunWith(PowerMockRunner::class)
|
||||||
@PrepareForTest(
|
@PrepareForTest(
|
||||||
ConstraintChecker::class, VirtualPumpPlugin::class, ToastUtils::class, Context::class,
|
ConstraintChecker::class, VirtualPumpPlugin::class, ToastUtils::class, Context::class,
|
||||||
TreatmentsPlugin::class, FabricPrivacy::class, LoggerUtils::class, PowerManager::class)
|
FabricPrivacy::class, LoggerUtils::class, PowerManager::class)
|
||||||
class QueueThreadTest : TestBaseWithProfile() {
|
class QueueThreadTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: ConstraintChecker
|
@Mock lateinit var constraintChecker: ConstraintChecker
|
||||||
|
|
|
@ -13,7 +13,6 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
@ -40,7 +39,6 @@ class BolusWizardTest : TestBase() {
|
||||||
@Mock lateinit var commandQueue: CommandQueueProvider
|
@Mock lateinit var commandQueue: CommandQueueProvider
|
||||||
@Mock lateinit var loopPlugin: LoopPlugin
|
@Mock lateinit var loopPlugin: LoopPlugin
|
||||||
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
||||||
@Mock lateinit var treatmentsPlugin: TreatmentsPlugin
|
|
||||||
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
||||||
@Mock lateinit var dateUtil: DateUtil
|
@Mock lateinit var dateUtil: DateUtil
|
||||||
@Mock lateinit var autosensDataStore: AutosensDataStore
|
@Mock lateinit var autosensDataStore: AutosensDataStore
|
||||||
|
@ -71,7 +69,6 @@ class BolusWizardTest : TestBase() {
|
||||||
`when`(profile.getIc()).thenReturn(insulinToCarbRatio)
|
`when`(profile.getIc()).thenReturn(insulinToCarbRatio)
|
||||||
|
|
||||||
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
|
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
|
||||||
`when`(activePlugin.activeTreatments).thenReturn(treatmentsPlugin)
|
|
||||||
`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
|
`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
|
||||||
`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
|
`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
|
||||||
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
|
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
|
||||||
|
|
|
@ -15,7 +15,6 @@ import info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnig
|
||||||
import info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl
|
import info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl
|
||||||
import info.nightscout.androidaps.interfaces.Profile.ProfileValue
|
import info.nightscout.androidaps.interfaces.Profile.ProfileValue
|
||||||
import info.nightscout.androidaps.interfaces.Pump
|
import info.nightscout.androidaps.interfaces.Pump
|
||||||
import info.nightscout.androidaps.interfaces.PumpDescription
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||||
|
@ -153,6 +152,7 @@ sealed class ProfileSealed(
|
||||||
if (getIcTimeFromMidnight(seconds) != profile.getIcTimeFromMidnight(seconds)) return false
|
if (getIcTimeFromMidnight(seconds) != profile.getIcTimeFromMidnight(seconds)) return false
|
||||||
if (getTargetLowMgdlTimeFromMidnight(seconds) != profile.getTargetLowMgdlTimeFromMidnight(seconds)) return false
|
if (getTargetLowMgdlTimeFromMidnight(seconds) != profile.getTargetLowMgdlTimeFromMidnight(seconds)) return false
|
||||||
if (getTargetHighMgdlTimeFromMidnight(seconds) != profile.getTargetHighMgdlTimeFromMidnight(seconds)) return false
|
if (getTargetHighMgdlTimeFromMidnight(seconds) != profile.getTargetHighMgdlTimeFromMidnight(seconds)) return false
|
||||||
|
if (dia != profile.dia) return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,5 +38,5 @@ interface CommandQueueProvider {
|
||||||
fun isCustomCommandRunning(customCommandType: Class<out CustomCommand>): Boolean
|
fun isCustomCommandRunning(customCommandType: Class<out CustomCommand>): Boolean
|
||||||
fun isCustomCommandInQueue(customCommandType: Class<out CustomCommand>): Boolean
|
fun isCustomCommandInQueue(customCommandType: Class<out CustomCommand>): Boolean
|
||||||
fun spannedStatus(): Spanned
|
fun spannedStatus(): Spanned
|
||||||
fun isThisProfileSet(profile: Profile): Boolean
|
fun isThisProfileSet(requestedProfile: Profile): Boolean
|
||||||
}
|
}
|
|
@ -31,6 +31,15 @@ class ProfileStore(val injector: HasAndroidInjector, val data: JSONObject, val d
|
||||||
return null
|
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 getDefaultProfile(): PureProfile? = getDefaultProfileName()?.let { getSpecificProfile(it) }
|
||||||
fun getDefaultProfileJson(): JSONObject? = getDefaultProfileName()?.let { getSpecificProfileJson(it) }
|
fun getDefaultProfileJson(): JSONObject? = getDefaultProfileName()?.let { getSpecificProfileJson(it) }
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class DetailedBolusInfoStorage @Inject constructor(
|
||||||
val d = store[i]
|
val d = store[i]
|
||||||
//aapsLogger.debug(LTag.PUMP, "Existing bolus info: " + 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) {
|
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)
|
store.removeAt(i)
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
@ -38,22 +38,22 @@ class DetailedBolusInfoStorage @Inject constructor(
|
||||||
for (i in store.indices) {
|
for (i in store.indices) {
|
||||||
val d = store[i]
|
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) {
|
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)
|
store.removeAt(i)
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If not found, use last record if amount is the same
|
// If not found, use last record if amount is the same
|
||||||
if (store.size > 0) {
|
// if (store.size > 0) {
|
||||||
val d = store[store.size - 1]
|
// val d = store[store.size - 1]
|
||||||
if (abs(d.insulin - bolus) < 0.01) {
|
// if (abs(d.insulin - bolus) < 0.01) {
|
||||||
aapsLogger.debug(LTag.PUMP, "Using LAST & removing bolus info: $d")
|
// aapsLogger.debug(LTag.PUMP, "Using LAST & removing bolus info for time $bolusTime: $d")
|
||||||
store.removeAt(store.size - 1)
|
// store.removeAt(store.size - 1)
|
||||||
return d
|
// return d
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
//Not found
|
//Not found
|
||||||
//aapsLogger.debug(LTag.PUMP, "Bolus info not found")
|
aapsLogger.debug(LTag.PUMP, "Bolus info not found for time $bolusTime")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.utils.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import com.jjoe64.graphview.GraphView
|
import com.jjoe64.graphview.GraphView
|
||||||
import com.jjoe64.graphview.series.DataPoint
|
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.core.R
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
import java.util.*
|
import java.util.ArrayList
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class ProfileGraph : GraphView {
|
class ProfileGraph : GraphView {
|
|
@ -371,7 +371,7 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<info.nightscout.androidaps.plugins.treatments.fragments.ProfileGraph
|
<info.nightscout.androidaps.utils.ui.ProfileGraph
|
||||||
android:id="@+id/basal_graph"
|
android:id="@+id/basal_graph"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="100dip"
|
android:layout_height="100dip"
|
||||||
|
|
|
@ -79,10 +79,10 @@ class DetailedBolusInfoStorageTest : TestBase() {
|
||||||
assertNull(d)
|
assertNull(d)
|
||||||
assertEquals(3, detailedBolusInfoStorage.store.size)
|
assertEquals(3, detailedBolusInfoStorage.store.size)
|
||||||
// Use last, if bolus size is the same
|
// Use last, if bolus size is the same
|
||||||
setUp()
|
// setUp()
|
||||||
d = detailedBolusInfoStorage.findDetailedBolusInfo(1070000, 5.0)
|
// d = detailedBolusInfoStorage.findDetailedBolusInfo(1070000, 5.0)
|
||||||
assertEquals(5.0, d!!.insulin, 0.01)
|
// assertEquals(5.0, d!!.insulin, 0.01)
|
||||||
assertEquals(2, detailedBolusInfoStorage.store.size)
|
// assertEquals(2, detailedBolusInfoStorage.store.size)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -62,9 +62,6 @@ class BLEComm @Inject internal constructor(
|
||||||
|
|
||||||
private const val PACKET_START_BYTE = 0xA5.toByte()
|
private const val PACKET_START_BYTE = 0xA5.toByte()
|
||||||
private const val PACKET_END_BYTE = 0x5A.toByte()
|
private const val PACKET_END_BYTE = 0x5A.toByte()
|
||||||
|
|
||||||
private const val BLE5_PACKET_START_BYTE = 0x73.toByte()
|
|
||||||
private const val BLE5_PACKET_END_BYTE = 0xBF.toByte()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var scheduledDisconnection: ScheduledFuture<*>? = null
|
private var scheduledDisconnection: ScheduledFuture<*>? = null
|
||||||
|
@ -326,13 +323,16 @@ class BLEComm @Inject internal constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private val readBuffer = ByteArray(1024)
|
private val readBuffer = ByteArray(1024)
|
||||||
private var bufferLength = 0
|
@Volatile private var bufferLength = 0
|
||||||
|
|
||||||
private fun addToReadBuffer(buffer: ByteArray) {
|
private fun addToReadBuffer(buffer: ByteArray) {
|
||||||
//log.debug("addToReadBuffer " + DanaRS_Packet.toHexString(buffer));
|
//log.debug("addToReadBuffer " + DanaRS_Packet.toHexString(buffer));
|
||||||
if (buffer.isEmpty()) {
|
if (buffer.isEmpty()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (bufferLength == 1024) {
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM, "1024 XXXXXXXXXXXXXX")
|
||||||
|
}
|
||||||
synchronized(readBuffer) {
|
synchronized(readBuffer) {
|
||||||
// Append incoming data to input buffer
|
// Append incoming data to input buffer
|
||||||
System.arraycopy(buffer, 0, readBuffer, bufferLength, buffer.size)
|
System.arraycopy(buffer, 0, readBuffer, bufferLength, buffer.size)
|
||||||
|
@ -342,21 +342,23 @@ class BLEComm @Inject internal constructor(
|
||||||
|
|
||||||
@kotlin.ExperimentalStdlibApi
|
@kotlin.ExperimentalStdlibApi
|
||||||
private fun readDataParsing(receivedData: ByteArray) {
|
private fun readDataParsing(receivedData: ByteArray) {
|
||||||
//aapsLogger.debug(LTag.PUMPBTCOMM, "readDataParsing")
|
//aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< readDataParsing " + DanaRS_Packet.toHexString(receivedData))
|
||||||
var startSignatureFound = false
|
var startSignatureFound = false
|
||||||
var packetIsValid = false
|
var packetIsValid = false
|
||||||
var isProcessing: Boolean
|
var isProcessing: Boolean
|
||||||
isProcessing = true
|
isProcessing = true
|
||||||
var inputBuffer: ByteArray? = null
|
var inputBuffer: ByteArray?
|
||||||
|
|
||||||
// decrypt 2nd level after successful connection
|
// decrypt 2nd level after successful connection
|
||||||
val incomingBuffer = if (encryption == EncryptionType.ENCRYPTION_RSv3 && isConnected)
|
val incomingBuffer =
|
||||||
bleEncryption.decryptSecondLevelPacket(receivedData).also {
|
if (isConnected && (encryption == EncryptionType.ENCRYPTION_RSv3 || encryption == EncryptionType.ENCRYPTION_BLE5))
|
||||||
encryptedDataRead = true
|
bleEncryption.decryptSecondLevelPacket(receivedData).also {
|
||||||
sp.putLong(R.string.key_rs_last_clear_key_request, 0L)
|
encryptedDataRead = true
|
||||||
}
|
sp.putLong(R.string.key_rs_last_clear_key_request, 0L)
|
||||||
else receivedData
|
}
|
||||||
|
else receivedData
|
||||||
addToReadBuffer(incomingBuffer)
|
addToReadBuffer(incomingBuffer)
|
||||||
|
//aapsLogger.debug(LTag.PUMPBTCOMM, "incomingBuffer " + DanaRS_Packet.toHexString(incomingBuffer))
|
||||||
|
|
||||||
while (isProcessing) {
|
while (isProcessing) {
|
||||||
var length = 0
|
var length = 0
|
||||||
|
@ -386,58 +388,29 @@ class BLEComm @Inject internal constructor(
|
||||||
// Verify packed end [5A 5A]
|
// Verify packed end [5A 5A]
|
||||||
if (readBuffer[length + 5] == PACKET_END_BYTE && readBuffer[length + 6] == PACKET_END_BYTE) {
|
if (readBuffer[length + 5] == PACKET_END_BYTE && readBuffer[length + 6] == PACKET_END_BYTE) {
|
||||||
packetIsValid = true
|
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) {
|
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
|
// decrypt the packet
|
||||||
bleEncryption.getDecryptedPacket(inputBuffer)?.let { decryptedBuffer ->
|
bleEncryption.getDecryptedPacket(inputBuffer)?.let { decryptedBuffer ->
|
||||||
if (decryptedBuffer[0] == BleEncryption.DANAR_PACKET__TYPE_ENCRYPTION_RESPONSE.toByte()) {
|
if (decryptedBuffer[0] == BleEncryption.DANAR_PACKET__TYPE_ENCRYPTION_RESPONSE.toByte()) {
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -16,7 +16,7 @@ internal interface GlucoseValueDao : TraceableDao<GlucoseValue> {
|
||||||
@Query("DELETE FROM $TABLE_GLUCOSE_VALUES")
|
@Query("DELETE FROM $TABLE_GLUCOSE_VALUES")
|
||||||
override fun deleteAllEntries()
|
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<GlucoseValue>
|
fun getLast(): Maybe<GlucoseValue>
|
||||||
|
|
||||||
@Query("SELECT id FROM $TABLE_GLUCOSE_VALUES ORDER BY id DESC limit 1")
|
@Query("SELECT id FROM $TABLE_GLUCOSE_VALUES ORDER BY id DESC limit 1")
|
||||||
|
|
Loading…
Reference in a new issue