carbs with duration
This commit is contained in:
parent
1ae4823a9a
commit
07d060c2b5
24 changed files with 2950 additions and 143 deletions
|
@ -3,6 +3,8 @@ package info.nightscout.androidaps.dependencyInjection
|
|||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.TherapyEventDataPoint
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
||||
|
||||
@Module
|
||||
|
|
|
@ -47,10 +47,10 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
|||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
||||
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
|
||||
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import info.nightscout.androidaps.plugins.source.DexcomPlugin
|
||||
|
@ -778,7 +778,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
if (config.APS && lastRun?.constraintsProcessed != null) {
|
||||
if (lastRun.constraintsProcessed!!.carbsReq > 0) {
|
||||
//only display carbsreq when carbs have not been entered recently
|
||||
val lastCarbsTime = repository.getLastBolusRecord()?.timestamp ?: 0L
|
||||
val lastCarb = repository.getLastCarbsRecordWrapped().blockingGet()
|
||||
val lastCarbsTime = if (lastCarb is ValueWrapper.Existing) lastCarb.value.timestamp else 0L
|
||||
if (lastCarbsTime < lastRun.lastAPSRun) {
|
||||
cobText = cobText + " | " + lastRun.constraintsProcessed!!.carbsReq + " " + resourceHelper.gs(R.string.required)
|
||||
}
|
||||
|
@ -862,7 +863,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
|
||||
// **** BG ****
|
||||
if (predictionsAvailable && menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, apsResult?.predictions)
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, apsResult?.predictions?.map { bg-> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper) }?.toMutableList())
|
||||
else graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null)
|
||||
|
||||
// Treatments
|
||||
|
|
|
@ -11,7 +11,8 @@ import com.jjoe64.graphview.series.Series
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.*
|
||||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.database.entities.Bolus
|
||||
|
@ -22,11 +23,7 @@ import info.nightscout.androidaps.logging.LTag
|
|||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.Round
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.utils.extensions.target
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.util.*
|
||||
|
@ -51,6 +48,7 @@ class GraphData(
|
|||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var translator: Translator
|
||||
|
||||
var maxY = Double.MIN_VALUE
|
||||
private var minY = Double.MAX_VALUE
|
||||
|
@ -77,7 +75,7 @@ class GraphData(
|
|||
for (bg in bgReadingsArray!!) {
|
||||
if (bg.timestamp < fromTime || bg.timestamp > toTime) continue
|
||||
if (bg.value > maxBgValue) maxBgValue = bg.value
|
||||
bgListArray.add(GlucoseValueDataPoint(injector, bg))
|
||||
bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper))
|
||||
}
|
||||
if (predictions != null) {
|
||||
predictions.sortWith(Comparator { o1: GlucoseValueDataPoint, o2: GlucoseValueDataPoint -> o1.x.compareTo(o2.x) })
|
||||
|
@ -247,7 +245,7 @@ class GraphData(
|
|||
it.y = getNearestBg(it.x.toLong())
|
||||
filteredTreatments.add(it)
|
||||
}
|
||||
repository.getCarbsIncludingInvalidFromTimeToTime(fromTime, endTime, true).blockingGet()
|
||||
repository.getCarbsIncludingInvalidFromTimeToTimeExpanded(fromTime, endTime, true).blockingGet()
|
||||
.map { CarbsDataPoint(it, resourceHelper) }
|
||||
.forEach {
|
||||
it.y = getNearestBg(it.x.toLong())
|
||||
|
@ -273,7 +271,7 @@ class GraphData(
|
|||
// Careportal
|
||||
// databaseHelper.getCareportalEventsFromTime(fromTime - 6 * 60 * 60 * 1000, true)
|
||||
repository.compatGetTherapyEventDataFromToTime(fromTime - T.hours(6).msecs(), endTime).blockingGet()
|
||||
.map { TherapyEventDataPoint(injector, it) }
|
||||
.map { TherapyEventDataPoint(it, resourceHelper, profileFunction, translator) }
|
||||
.filterTimeframe(fromTime, endTime)
|
||||
.forEach {
|
||||
if (it.y == 0.0) it.y = getNearestBg(it.x.toLong())
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package info.nightscout.androidaps.data
|
||||
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
|
||||
|
||||
import android.graphics.Color
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.database.entities.Bolus
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter.toPumpSupportedBolus
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import javax.inject.Inject
|
||||
|
@ -22,7 +20,7 @@ class BolusDataPoint @Inject constructor(
|
|||
|
||||
override fun getX(): Double = data.timestamp.toDouble()
|
||||
override fun getY(): Double = if (data.type == Bolus.Type.SMB) defaultValueHelper.determineLowLine() else yValue
|
||||
override fun getLabel(): String = toPumpSupportedBolus(data.amount, activePlugin.activePump, resourceHelper)
|
||||
override fun getLabel(): String = DecimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump, resourceHelper)
|
||||
override fun getDuration(): Long = 0
|
||||
override fun getSize(): Float = 2f
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package info.nightscout.androidaps.data
|
||||
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
|
||||
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.database.entities.Carbs
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -20,7 +18,7 @@ class CarbsDataPoint @Inject constructor(
|
|||
override fun getDuration(): Long = 0
|
||||
override fun getSize(): Float = 2f
|
||||
|
||||
override fun getShape(): PointsWithLabelGraphSeries.Shape = PointsWithLabelGraphSeries.Shape.BOLUS
|
||||
override fun getShape(): PointsWithLabelGraphSeries.Shape = PointsWithLabelGraphSeries.Shape.CARBS
|
||||
|
||||
override fun getColor(): Int =
|
||||
if (data.isValid) resourceHelper.gc(R.color.carbs)
|
|
@ -1,29 +1,20 @@
|
|||
package info.nightscout.androidaps.data
|
||||
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
class GlucoseValueDataPoint @Inject constructor(
|
||||
val injector: HasAndroidInjector,
|
||||
val data: GlucoseValue
|
||||
val data: GlucoseValue,
|
||||
private val defaultValueHelper: DefaultValueHelper,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val resourceHelper: ResourceHelper
|
||||
) : DataPointWithLabelInterface {
|
||||
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
|
||||
init {
|
||||
injector.androidInjector().inject(this)
|
||||
}
|
||||
|
||||
fun valueToUnits(units: String): Double =
|
||||
if (units == Constants.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
|
||||
|
||||
|
@ -59,11 +50,11 @@ class GlucoseValueDataPoint @Inject constructor(
|
|||
val predictionColor: Int
|
||||
get() {
|
||||
return when (data.sourceSensor) {
|
||||
GlucoseValue.SourceSensor.IOB_PREDICTION -> resourceHelper.gc(R.color.iob)
|
||||
GlucoseValue.SourceSensor.COB_PREDICTION -> resourceHelper.gc(R.color.cob)
|
||||
GlucoseValue.SourceSensor.IOB_PREDICTION -> resourceHelper.gc(R.color.iob)
|
||||
GlucoseValue.SourceSensor.COB_PREDICTION -> resourceHelper.gc(R.color.cob)
|
||||
GlucoseValue.SourceSensor.aCOB_PREDICTION -> -0x7f000001 and resourceHelper.gc(R.color.cob)
|
||||
GlucoseValue.SourceSensor.UAM_PREDICTION -> resourceHelper.gc(R.color.uam)
|
||||
GlucoseValue.SourceSensor.ZT_PREDICTION -> resourceHelper.gc(R.color.zt)
|
||||
GlucoseValue.SourceSensor.UAM_PREDICTION -> resourceHelper.gc(R.color.uam)
|
||||
GlucoseValue.SourceSensor.ZT_PREDICTION -> resourceHelper.gc(R.color.zt)
|
||||
else -> R.color.white
|
||||
}
|
||||
}
|
|
@ -1,35 +1,25 @@
|
|||
package info.nightscout.androidaps.data
|
||||
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
|
||||
|
||||
import android.graphics.Color
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||
import info.nightscout.androidaps.interfaces.Interval
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.Translator
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
class TherapyEventDataPoint @Inject constructor(
|
||||
val injector: HasAndroidInjector,
|
||||
val data: TherapyEvent
|
||||
val data: TherapyEvent,
|
||||
private val resourceHelper: ResourceHelper,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val translator: Translator
|
||||
) : DataPointWithLabelInterface, Interval {
|
||||
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var translator: Translator
|
||||
|
||||
private var yValue = 0.0
|
||||
|
||||
init {
|
||||
injector.androidInjector().inject(this)
|
||||
}
|
||||
|
||||
override fun getX(): Double {
|
||||
return data.timestamp.toDouble()
|
||||
}
|
|
@ -120,7 +120,7 @@ class UploadChunk @Inject constructor(
|
|||
.forEach { bolus ->
|
||||
result.add(BolusElement(bolus))
|
||||
}
|
||||
repository.getCarbsDataFromTimeToTime(start, end, true)
|
||||
repository.getCarbsDataFromTimeToTimeExpanded(start, end, true)
|
||||
.blockingGet()
|
||||
.forEach { carb ->
|
||||
result.add(WizardElement(carb))
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.google.android.gms.wearable.WearableListenerService;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -31,7 +32,7 @@ import dagger.android.AndroidInjection;
|
|||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseValueDataPoint;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.database.AppRepository;
|
||||
|
@ -530,12 +531,15 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
|||
.stream()
|
||||
.filter(bolus -> bolus.getType() != Bolus.Type.PRIMING)
|
||||
.forEach(bolus -> boluses.add(treatmentMap(bolus.getTimestamp(), bolus.getAmount(), 0, bolus.getType() == Bolus.Type.SMB, bolus.isValid())));
|
||||
repository.getCarbsIncludingInvalidFromTime(startTimeWindow, true).blockingGet()
|
||||
repository.getCarbsDataFromTimeExpanded(startTimeWindow, true).blockingGet()
|
||||
.forEach(carb -> boluses.add(treatmentMap(carb.getTimestamp(), 0, carb.getAmount(), false, carb.isValid())));
|
||||
|
||||
final LoopPlugin.LastRun finalLastRun = loopPlugin.getLastRun();
|
||||
if (sp.getBoolean("wear_predictions", true) && finalLastRun != null && finalLastRun.getRequest().getHasPredictions() && finalLastRun.getConstraintsProcessed() != null) {
|
||||
List<GlucoseValueDataPoint> predArray = finalLastRun.getConstraintsProcessed().getPredictions();
|
||||
List<GlucoseValueDataPoint> predArray =
|
||||
finalLastRun.getConstraintsProcessed().getPredictions()
|
||||
.stream().map( bg -> new GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!predArray.isEmpty()) {
|
||||
final String units = profileFunction.getUnits();
|
||||
|
|
|
@ -28,7 +28,6 @@ import info.nightscout.androidaps.utils.DateUtil
|
|||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.extensions.expandCarbs
|
||||
import info.nightscout.androidaps.utils.extensions.iobCalc
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
|
@ -532,8 +531,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
var displayCob: Double? = null
|
||||
var futureCarbs = 0.0
|
||||
val now = DateUtil.now()
|
||||
val carbs = repository.getCarbsDataFromTime(now, true)
|
||||
.blockingGet()
|
||||
val carbs = repository.getCarbsDataFromTimeExpanded(now, true).blockingGet()
|
||||
if (autosensData != null) {
|
||||
displayCob = autosensData.cob
|
||||
carbs.forEach { carb ->
|
||||
|
@ -603,8 +601,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
}
|
||||
val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong()
|
||||
repository.getCarbsDataFromTimeToTime(absorptionTimeAgo + 1, now, true)
|
||||
.map { it.map { c -> c.expandCarbs() }.flatten() }
|
||||
repository.getCarbsDataFromTimeToTimeExpanded(absorptionTimeAgo + 1, now, true)
|
||||
.blockingGet()
|
||||
.forEach {
|
||||
if (it.amount > 0) {
|
||||
|
|
|
@ -189,7 +189,7 @@ class IobCobOref1Thread internal constructor(
|
|||
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + "null")
|
||||
}
|
||||
}
|
||||
val recentCarbTreatments = repository.getCarbsDataFromTimeToTime(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
|
||||
val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
|
||||
for (recentCarbTreatment in recentCarbTreatments) {
|
||||
autosensData.carbsFromBolus += recentCarbTreatment.amount
|
||||
val isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()
|
||||
|
|
|
@ -188,7 +188,7 @@ class IobCobThread @Inject internal constructor(
|
|||
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + "null")
|
||||
}
|
||||
}
|
||||
val recentCarbTreatments = repository.getCarbsDataFromTimeToTime(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
|
||||
val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
|
||||
for (recentCarbTreatment in recentCarbTreatments) {
|
||||
autosensData.carbsFromBolus += recentCarbTreatment.amount
|
||||
val isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()
|
||||
|
|
|
@ -293,7 +293,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
ml.carbs?.let { carbs ->
|
||||
holder.binding.carbsDate.text = dateUtil.timeString(carbs.timestamp)
|
||||
holder.binding.carbs.text = resourceHelper.gs(R.string.format_carbs, carbs.amount.toInt())
|
||||
holder.binding.carbsDuration.text = resourceHelper.gs(R.string.format_mins, T.msecs(carbs.duration).mins().toInt())
|
||||
holder.binding.carbsDuration.text = if (carbs.duration> 0) resourceHelper.gs(R.string.format_mins, T.msecs(carbs.duration).mins().toInt()) else ""
|
||||
holder.binding.carbsNs.visibility = (NSUpload.isIdValid(carbs.interfaceIDs.nightscoutId)).toVisibility()
|
||||
holder.binding.carbsPump.visibility = (carbs.interfaceIDs.pumpId != null).toVisibility()
|
||||
holder.binding.carbsInvalid.visibility = carbs.isValid.not().toVisibility()
|
||||
|
|
|
@ -65,7 +65,7 @@ class TddCalculator @Inject constructor(
|
|||
tdd.bolus += t.amount
|
||||
result.put(midnight, tdd)
|
||||
}
|
||||
repository.getCarbsDataFromTimeToTime(startTime, endTime, true).blockingGet().forEach { t->
|
||||
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t->
|
||||
val midnight = MidnightTime.calc(t.timestamp)
|
||||
val tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0)
|
||||
tdd.carbs += t.amount
|
||||
|
|
|
@ -205,6 +205,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -2,10 +2,8 @@ package info.nightscout.androidaps.core.di
|
|||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.data.GlucoseValueDataPoint
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.data.TherapyEventDataPoint
|
||||
import info.nightscout.androidaps.db.ExtendedBolus
|
||||
import info.nightscout.androidaps.db.ProfileSwitch
|
||||
import info.nightscout.androidaps.db.TemporaryBasal
|
||||
|
@ -31,6 +29,4 @@ abstract class CoreDataClassesModule {
|
|||
@ContributesAndroidInjector abstract fun profileSwitchInjector(): ProfileSwitch
|
||||
@ContributesAndroidInjector abstract fun temporaryBasalInjector(): TemporaryBasal
|
||||
@ContributesAndroidInjector abstract fun extendedBolusInjector(): ExtendedBolus
|
||||
@ContributesAndroidInjector abstract fun glucoseValueDataPointInjector(): GlucoseValueDataPoint
|
||||
@ContributesAndroidInjector abstract fun therapyEventDataPointInjector(): TherapyEventDataPoint
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.aps.loop
|
|||
import android.text.Spanned
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.data.GlucoseValueDataPoint
|
||||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
|
@ -185,9 +184,9 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
return json
|
||||
}
|
||||
|
||||
val predictions: MutableList<GlucoseValueDataPoint>
|
||||
val predictions: MutableList<GlucoseValue>
|
||||
get() {
|
||||
val array: MutableList<GlucoseValueDataPoint> = ArrayList()
|
||||
val array: MutableList<GlucoseValue> = ArrayList()
|
||||
val startTime = date
|
||||
json?.let { json ->
|
||||
if (json.has("predBGs")) {
|
||||
|
@ -203,7 +202,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
sourceSensor = GlucoseValue.SourceSensor.IOB_PREDICTION,
|
||||
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||
)
|
||||
array.add(GlucoseValueDataPoint(injector, gv))
|
||||
array.add(gv)
|
||||
}
|
||||
}
|
||||
if (predBGs.has("aCOB")) {
|
||||
|
@ -217,7 +216,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
sourceSensor = GlucoseValue.SourceSensor.aCOB_PREDICTION,
|
||||
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||
)
|
||||
array.add(GlucoseValueDataPoint(injector, gv))
|
||||
array.add(gv)
|
||||
}
|
||||
}
|
||||
if (predBGs.has("COB")) {
|
||||
|
@ -231,7 +230,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
sourceSensor = GlucoseValue.SourceSensor.COB_PREDICTION,
|
||||
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||
)
|
||||
array.add(GlucoseValueDataPoint(injector, gv))
|
||||
array.add(gv)
|
||||
}
|
||||
}
|
||||
if (predBGs.has("UAM")) {
|
||||
|
@ -245,7 +244,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
sourceSensor = GlucoseValue.SourceSensor.UAM_PREDICTION,
|
||||
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||
)
|
||||
array.add(GlucoseValueDataPoint(injector, gv))
|
||||
array.add(gv)
|
||||
}
|
||||
}
|
||||
if (predBGs.has("ZT")) {
|
||||
|
@ -259,7 +258,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
|||
sourceSensor = GlucoseValue.SourceSensor.ZT_PREDICTION,
|
||||
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||
)
|
||||
array.add(GlucoseValueDataPoint(injector, gv))
|
||||
array.add(gv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,12 @@ package info.nightscout.androidaps.plugins.general.overview.graphExtensions;
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* with the "Linking Exception" along with this program; if not,
|
||||
* write to the author Jonas Gehring <g.jjoe64@gmail.com>.
|
||||
* <p>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Added by mike
|
||||
*/
|
||||
|
||||
/**
|
||||
* Added by mike
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
|
@ -61,6 +58,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
TRIANGLE,
|
||||
RECTANGLE,
|
||||
BOLUS,
|
||||
CARBS,
|
||||
SMB,
|
||||
EXTENDEDBOLUS,
|
||||
PROFILE,
|
||||
|
@ -233,7 +231,18 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
drawArrows(points, canvas, mPaint);
|
||||
if (value.getLabel() != null) {
|
||||
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
}
|
||||
} else if (value.getShape() == Shape.CARBS) {
|
||||
mPaint.setStrokeWidth(0);
|
||||
Point[] points = new Point[3];
|
||||
points[0] = new Point((int) endX, (int) (endY - scaledPxSize));
|
||||
points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67));
|
||||
points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67));
|
||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
drawArrows(points, canvas, mPaint);
|
||||
if (value.getLabel() != null) {
|
||||
drawLabel45Left(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
}
|
||||
} else if (value.getShape() == Shape.SMB) {
|
||||
mPaint.setStrokeWidth(2);
|
||||
|
@ -282,21 +291,21 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
|
||||
if (value.getLabel() != null) {
|
||||
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
}
|
||||
} else if (value.getShape() == Shape.ANNOUNCEMENT) {
|
||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
|
||||
if (value.getLabel() != null) {
|
||||
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
}
|
||||
} else if (value.getShape() == Shape.GENERAL) {
|
||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
|
||||
if (value.getLabel() != null) {
|
||||
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
|
||||
}
|
||||
} else if (value.getShape() == Shape.EXERCISE) {
|
||||
mPaint.setStrokeWidth(0);
|
||||
|
@ -380,29 +389,29 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
canvas.restore();
|
||||
}
|
||||
|
||||
void drawLabel45(float endX, float endY, E value, Canvas canvas, Float scaledPxSize, Float scaledTextSize) {
|
||||
if (value.getLabel().startsWith("~")) {
|
||||
float px = endX;
|
||||
float py = endY + scaledPxSize;
|
||||
canvas.save();
|
||||
canvas.rotate(-45, px, py);
|
||||
mPaint.setTextSize((float) (scaledTextSize * 0.8));
|
||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
||||
mPaint.setFakeBoldText(true);
|
||||
mPaint.setTextAlign(Paint.Align.RIGHT);
|
||||
canvas.drawText(value.getLabel().substring(1), px - scaledPxSize, py, mPaint);
|
||||
mPaint.setTextAlign(Paint.Align.LEFT);
|
||||
canvas.restore();
|
||||
} else {
|
||||
float px = endX;
|
||||
float py = endY - scaledPxSize;
|
||||
canvas.save();
|
||||
canvas.rotate(-45, px, py);
|
||||
mPaint.setTextSize((float) (scaledTextSize * 0.8));
|
||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
||||
mPaint.setFakeBoldText(true);
|
||||
canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);
|
||||
canvas.restore();
|
||||
}
|
||||
void drawLabel45Right(float endX, float endY, E value, Canvas canvas, Float scaledPxSize, Float scaledTextSize) {
|
||||
float px = endX;
|
||||
float py = endY - scaledPxSize;
|
||||
canvas.save();
|
||||
canvas.rotate(-45, px, py);
|
||||
mPaint.setTextSize((float) (scaledTextSize * 0.8));
|
||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
||||
mPaint.setFakeBoldText(true);
|
||||
canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
void drawLabel45Left(float endX, float endY, E value, Canvas canvas, Float scaledPxSize, Float scaledTextSize) {
|
||||
float px = endX;
|
||||
float py = endY + scaledPxSize;
|
||||
canvas.save();
|
||||
canvas.rotate(-45, px, py);
|
||||
mPaint.setTextSize((float) (scaledTextSize * 0.8));
|
||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
||||
mPaint.setFakeBoldText(true);
|
||||
mPaint.setTextAlign(Paint.Align.RIGHT);
|
||||
canvas.drawText(value.getLabel(), px - scaledPxSize, py, mPaint);
|
||||
mPaint.setTextAlign(Paint.Align.LEFT);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,31 +5,7 @@ import info.nightscout.androidaps.database.entities.Carbs
|
|||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import org.json.JSONObject
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun Carbs.expandCarbs(): List<Carbs> =
|
||||
mutableListOf<Carbs>().also { carbs ->
|
||||
if (this.duration == 0L) {
|
||||
carbs.add(this)
|
||||
} else {
|
||||
var remainingCarbs = this.amount
|
||||
val ticks = T.msecs(this.duration).hours() * 4 //duration guaranteed to be integer greater zero
|
||||
for (i in 0 until ticks) {
|
||||
val carbTime = this.timestamp + i * 15 * 60 * 1000
|
||||
val smallCarbAmount = (1.0 * remainingCarbs / (ticks - i)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
|
||||
remainingCarbs -= smallCarbAmount.toLong()
|
||||
if (smallCarbAmount > 0)
|
||||
carbs.add(Carbs(
|
||||
timestamp = carbTime,
|
||||
amount = smallCarbAmount.toDouble(),
|
||||
duration = 0
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Carbs.toJson(): JSONObject =
|
||||
JSONObject()
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,6 +12,7 @@ import io.reactivex.subjects.PublishSubject
|
|||
import java.util.concurrent.Callable
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Singleton
|
||||
open class AppRepository @Inject internal constructor(
|
||||
|
@ -310,6 +311,27 @@ open class AppRepository @Inject internal constructor(
|
|||
database.bolusDao.deleteAllEntries()
|
||||
|
||||
// CARBS
|
||||
|
||||
val timeBackForExpand = 8 * 60 * 60 * 1000
|
||||
private fun expandCarbs(carbs: Carbs): List<Carbs> =
|
||||
if (carbs.duration == 0L) {
|
||||
listOf(carbs)
|
||||
} else {
|
||||
var remainingCarbs = carbs.amount
|
||||
val ticks = (carbs.duration / 1000 / 60 / 15).coerceAtLeast(1L)
|
||||
(0 until ticks).map {
|
||||
val carbTime = carbs.timestamp + it * 15 * 60 * 1000
|
||||
val smallCarbAmount = (1.0 * remainingCarbs / (ticks - it)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
|
||||
remainingCarbs -= smallCarbAmount.toLong()
|
||||
Carbs(timestamp = carbTime, amount = smallCarbAmount.toDouble(), duration = 0)
|
||||
}.filter { it.amount != 0.0 }
|
||||
}
|
||||
|
||||
private fun Single<List<Carbs>>.expand() = this.map { it.map(::expandCarbs).flatten() }
|
||||
private fun Single<List<Carbs>>.filterOutExtended() = this.map { it.filter { c -> c.duration == 0L } }
|
||||
private fun Single<List<Carbs>>.fromTo(from: Long, to: Long) = this.map { it.filter { c -> c.timestamp in from..to } }
|
||||
private fun Single<List<Carbs>>.sort() = this.map { it.sortedBy { c -> c.timestamp } }
|
||||
|
||||
/*
|
||||
* returns a Pair of the next entity to sync and the ID of the "update".
|
||||
* The update id might either be the entry id itself if it is a new entry - or the id
|
||||
|
@ -339,6 +361,11 @@ open class AppRepository @Inject internal constructor(
|
|||
fun getLastCarbsRecord(): Carbs? =
|
||||
database.carbsDao.getLastCarbsRecord()
|
||||
|
||||
fun getLastCarbsRecordWrapped(): Single<ValueWrapper<Carbs>> =
|
||||
database.carbsDao.getLastCarbsRecordMaybe()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
fun getOldestCarbsRecord(): Carbs? =
|
||||
database.carbsDao.getOldestCarbsRecord()
|
||||
|
||||
|
@ -347,18 +374,35 @@ open class AppRepository @Inject internal constructor(
|
|||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getCarbsDataFromTimeExpanded(timestamp: Long, ascending: Boolean): Single<List<Carbs>> =
|
||||
database.carbsDao.getCarbsFromTime(timestamp - timeBackForExpand)
|
||||
.expand()
|
||||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getCarbsDataFromTimeToTime(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
|
||||
database.carbsDao.getCarbsFromTimeToTime(from, to)
|
||||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getCarbsIncludingInvalidFromTime(timestamp: Long, ascending: Boolean): Single<List<Carbs>> =
|
||||
database.carbsDao.getCarbsIncludingInvalidFromTime(timestamp)
|
||||
fun getCarbsDataFromTimeToTimeExpanded(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
|
||||
database.carbsDao.getCarbsFromTimeToTime(from - timeBackForExpand, to)
|
||||
.expand()
|
||||
.fromTo(from, to)
|
||||
.sort()
|
||||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getCarbsIncludingInvalidFromTimeToTime(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
|
||||
database.carbsDao.getCarbsIncludingInvalidFromTimeToTime(from, to)
|
||||
fun getCarbsIncludingInvalidFromTime(timestamp: Long, ascending: Boolean): Single<List<Carbs>> =
|
||||
database.carbsDao.getCarbsIncludingInvalidFromTime(timestamp - timeBackForExpand)
|
||||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getCarbsIncludingInvalidFromTimeToTimeExpanded(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
|
||||
database.carbsDao.getCarbsIncludingInvalidFromTimeToTime(from - timeBackForExpand, to)
|
||||
.expand()
|
||||
.fromTo(from, to)
|
||||
.sort()
|
||||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ internal interface CarbsDao : TraceableDao<Carbs> {
|
|||
@Query("SELECT * FROM $TABLE_CARBS WHERE isValid = 1 AND referenceId IS NULL ORDER BY id DESC LIMIT 1")
|
||||
fun getLastCarbsRecord(): Carbs?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CARBS WHERE isValid = 1 AND referenceId IS NULL ORDER BY id DESC LIMIT 1")
|
||||
fun getLastCarbsRecordMaybe(): Maybe<Carbs>
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CARBS WHERE isValid = 1 AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
|
||||
fun getOldestCarbsRecord(): Carbs?
|
||||
|
||||
|
|
Loading…
Reference in a new issue