From bce387dba8970b8897cc318bd228c5836d0a2de2 Mon Sep 17 00:00:00 2001 From: Sergey Zorchenko Date: Wed, 29 Jun 2022 01:48:22 +0300 Subject: [PATCH] bg data smoothing --- .../androidaps/dialogs/WizardDialog.kt | 2 +- .../plugins/general/autotune/data/BGDatum.kt | 2 +- .../general/overview/OverviewFragment.kt | 2 +- .../PersistentNotificationPlugin.kt | 4 +- .../wear/wearintegration/DataHandlerMobile.kt | 6 +- .../IobCobCalculatorPlugin.kt | 2 +- .../iob/iobCobCalculator/IobCobOref1Worker.kt | 8 +- .../iob/iobCobCalculator/IobCobOrefWorker.kt | 8 +- .../androidaps/plugins/source/AidexPlugin.kt | 1 + .../plugins/source/BGSourceFragment.kt | 6 +- .../androidaps/plugins/source/DexcomPlugin.kt | 3 +- .../plugins/source/EversensePlugin.kt | 1 + .../androidaps/plugins/source/GlimpPlugin.kt | 1 + .../plugins/source/GlunovoPlugin.kt | 1 + .../plugins/source/IntelligoPlugin.kt | 1 + .../androidaps/plugins/source/MM640gPlugin.kt | 1 + .../plugins/source/NSClientSourcePlugin.kt | 3 +- .../plugins/source/PoctechPlugin.kt | 1 + .../plugins/source/RandomBgPlugin.kt | 1 + .../androidaps/plugins/source/TomatoPlugin.kt | 1 + .../androidaps/plugins/source/XdripPlugin.kt | 1 + .../utils/wizard/QuickWizardEntry.kt | 2 +- .../workflow/PrepareBgDataWorker.kt | 9 +- .../workflow/PrepareBucketedDataWorker.kt | 4 +- .../workflow/PreparePredictionsWorker.kt | 4 +- .../workflow/PrepareTreatmentsDataWorker.kt | 8 +- app/src/main/res/values-ru-rRU/strings.xml | 7 + app/src/main/res/values/strings.xml | 6 + app/src/main/res/xml/pref_overview.xml | 6 + .../androidaps/data/InMemoryGlucoseValue.kt | 14 +- .../extensions/GlucoseValueExtension.kt | 28 +- .../androidaps/plugins/aps/loop/APSResult.kt | 5 + .../plugins/general/overview/OverviewData.kt | 4 +- .../graphExtensions/GlucoseValueDataPoint.kt | 9 +- .../InMemoryGlucoseValueDataPoint.kt | 7 +- .../iob/iobCobCalculator/AutosensDataStore.kt | 39 +- .../iobCobCalculator/GlucoseStatusProvider.kt | 16 +- .../androidaps/utils/TrendCalculator.kt | 7 +- core/src/main/res/values/strings.xml | 1 + .../22.json | 117 +- .../23.json | 3700 +++++++++++++++++ .../androidaps/database/AppDatabase.kt | 2 +- .../androidaps/database/DatabaseModule.kt | 37 +- .../database/entities/GlucoseValue.kt | 1 + .../transactions/CgmSourceTransaction.kt | 131 +- .../smsCommunicator/SmsCommunicatorPlugin.kt | 4 +- .../SmsCommunicatorPluginTest.kt | 2 +- .../info/nightscout/ui/dialogs/CarbsDialog.kt | 3 +- .../java/info/nightscout/ui/widget/Widget.kt | 2 +- 49 files changed, 4139 insertions(+), 92 deletions(-) create mode 100644 database/schemas/info.nightscout.androidaps.database.AppDatabase/23.json diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index 7918dffd319..07554c91970 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -367,7 +367,7 @@ class WizardDialog : DaggerDialogFragment() { binding.bgInput.step = if (units == GlucoseUnit.MGDL) 1.0 else 0.1 // Set BG if not old - binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0 + binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units, sp) ?: 0.0 binding.ttCheckbox.isEnabled = tempTarget is ValueWrapper.Existing binding.ttCheckboxIcon.visibility = binding.ttCheckbox.isEnabled.toVisibility() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/BGDatum.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/BGDatum.kt index 7d2f7b6f8ce..2d019a410a3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/BGDatum.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/BGDatum.kt @@ -31,7 +31,7 @@ class BGDatum { constructor(json: JSONObject, dateUtil: DateUtil) { this.dateUtil = dateUtil try { - //if (json.has("_id")) id = json.getLong("_id") + if (json.has("_id")) id = json.getLong("_id") if (json.has("date")) date = json.getLong("date") if (json.has("sgv")) value = json.getDouble("sgv") if (json.has("direction")) direction = TrendArrow.fromString(json.getString("direction")) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index dd7735c1e85..7593fd8a12a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -798,7 +798,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList val lastBgDescription = overviewData.lastBgDescription runOnUiThread { _binding ?: return@runOnUiThread - binding.infoLayout.bg.text = lastBg?.valueToUnitsString(units) + binding.infoLayout.bg.text = lastBg?.valueToUnitsString(units, sp) ?: rh.gs(R.string.value_unavailable_short) binding.infoLayout.bg.setTextColor(lastBgColor) binding.infoLayout.arrow.setImageResource(trendArrow.directionToIcon()) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.kt index 0a4072250b5..8a7d7850abc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.kt @@ -23,6 +23,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import javax.inject.Inject @@ -34,6 +35,7 @@ class PersistentNotificationPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, rh: ResourceHelper, + private val sp: SP, private val aapsSchedulers: AapsSchedulers, private val profileFunction: ProfileFunction, private val fabricPrivacy: FabricPrivacy, @@ -112,7 +114,7 @@ class PersistentNotificationPlugin @Inject constructor( val lastBG = iobCobCalculator.ads.lastBg() val glucoseStatus = glucoseStatusProvider.glucoseStatusData if (lastBG != null) { - line1aa = lastBG.valueToUnitsString(units) + line1aa = lastBG.valueToUnitsString(units, sp) line1 = line1aa if (glucoseStatus != null) { line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt index 19fa03887b1..f5bf89fd53a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -366,7 +366,7 @@ class DataHandlerMobile @Inject constructor( tempTarget = tempTarget, carbs = carbsAfterConstraints, cob = cobInfo.displayCob!!, - bg = bgReading.valueToUnits(profileFunction.getUnits()), + bg = bgReading.valueToUnits(profileFunction.getUnits(), sp), correction = 0.0, percentageCorrection = percentage, useBg = sp.getBoolean(R.string.key_wearwizard_bg, true), @@ -830,7 +830,7 @@ class DataHandlerMobile @Inject constructor( val finalLastRun = loop.lastRun if (sp.getBoolean("wear_predictions", true) && finalLastRun?.request?.hasPredictions == true && finalLastRun.constraintsProcessed != null) { val predArray = finalLastRun.constraintsProcessed!!.predictions - .stream().map { bg: GlucoseValue -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh) } + .stream().map { bg: GlucoseValue -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh, sp) } .collect(Collectors.toList()) if (predArray.isNotEmpty()) for (bg in predArray) if (bg.data.value > 39) @@ -917,7 +917,7 @@ class DataHandlerMobile @Inject constructor( return EventData.SingleBg( timeStamp = glucoseValue.timestamp, - sgvString = glucoseValue.valueToUnitsString(units), + sgvString = glucoseValue.valueToUnitsString(units, sp), glucoseUnits = units.asText, slopeArrow = trendCalculator.getTrendArrow(glucoseValue).symbol, delta = glucoseStatus?.let { deltaString(it.delta, it.delta * Constants.MGDL_TO_MMOLL, units) } ?: "--", diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt index a6f96631d8f..c0f166721da 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt @@ -86,7 +86,7 @@ class IobCobCalculatorPlugin @Inject constructor( private var iobTable = LongSparseArray() // oldest at index 0 private var basalDataTable = LongSparseArray() // oldest at index 0 - override var ads: AutosensDataStore = AutosensDataStore() + override var ads: AutosensDataStore = AutosensDataStore(sp) private val dataLock = Any() private var thread: Thread? = null diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt index b5bb5f79ff3..19823eda0ec 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt @@ -133,14 +133,14 @@ class IobCobOref1Worker( //console.error(bgTime , bucketed_data[i].glucose); var avgDelta: Double var delta: Double - val bg: Double = bucketedData[i].value - if (bg < 39 || bucketedData[i + 3].value < 39) { + val bg: Double = bucketedData[i].rawOrSmoothed(sp) + if (bg < 39 || bucketedData[i + 3].rawOrSmoothed(sp) < 39) { aapsLogger.error("! value < 39") continue } autosensData.bg = bg - delta = bg - bucketedData[i + 1].value - avgDelta = (bg - bucketedData[i + 3].value) / 3 + delta = bg - bucketedData[i + 1].rawOrSmoothed(sp) + avgDelta = (bg - bucketedData[i + 3].rawOrSmoothed(sp)) / 3 val iob = data.iobCobCalculator.calculateFromTreatmentsAndTemps(bgTime, profile) val bgi = -iob.activity * sens * 5 val deviation = delta - bgi diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt index b22f0927194..f14da3bf281 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt @@ -128,14 +128,14 @@ class IobCobOrefWorker @Inject internal constructor( //console.error(bgTime , bucketed_data[i].glucose); var avgDelta: Double var delta: Double - val bg: Double = bucketedData[i].value - if (bg < 39 || bucketedData[i + 3].value < 39) { + val bg: Double = bucketedData[i].rawOrSmoothed(sp) + if (bg < 39 || bucketedData[i + 3].rawOrSmoothed(sp) < 39) { aapsLogger.error("! value < 39") continue } autosensData.bg = bg - delta = bg - bucketedData[i + 1].value - avgDelta = (bg - bucketedData[i + 3].value) / 3 + delta = bg - bucketedData[i + 1].rawOrSmoothed(sp) + avgDelta = (bg - bucketedData[i + 3].rawOrSmoothed(sp)) / 3 val iob = data.iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime, profile) val bgi = -iob.activity * sens * 5 val deviation = delta - bgi diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt index 21d4a75b0f2..dd1edee2b6d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt @@ -93,6 +93,7 @@ class AidexPlugin @Inject constructor( glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( timestamp = timestamp, value = bgValueTarget, + smoothed = null, raw = null, noise = null, trendArrow = GlucoseValue.TrendArrow.fromString(bundle.getString(Intents.AIDEX_BG_SLOPE_NAME)), diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt index 62662133264..74de6b1dd71 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.kt @@ -36,6 +36,7 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag +import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import java.util.concurrent.TimeUnit @@ -53,6 +54,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider { @Inject lateinit var uel: UserEntryLogger @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var sp: SP private val disposable = CompositeDisposable() private val millsToThePast = T.hours(36).msecs() @@ -137,7 +139,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider { holder.binding.date.visibility = newDay.toVisibility() holder.binding.date.text = if (newDay) dateUtil.dateStringRelative(glucoseValue.timestamp, rh) else "" holder.binding.time.text = dateUtil.timeString(glucoseValue.timestamp) - holder.binding.value.text = glucoseValue.valueToUnitsString(profileFunction.getUnits()) + holder.binding.value.text = glucoseValue.valueToUnitsString(profileFunction.getUnits(), sp) holder.binding.direction.setImageResource(glucoseValue.trendArrow.directionToIcon()) if (position > 0) { val previous = glucoseValues[position - 1] @@ -178,7 +180,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider { private fun getConfirmationText(selectedItems: SparseArray): String { if (selectedItems.size() == 1) { val glucoseValue = selectedItems.valueAt(0) - return dateUtil.dateAndTimeString(glucoseValue.timestamp) + "\n" + glucoseValue.valueToUnitsString(profileFunction.getUnits()) + return dateUtil.dateAndTimeString(glucoseValue.timestamp) + "\n" + glucoseValue.valueToUnitsString(profileFunction.getUnits(), sp) } return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size()) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt index b48dc49fd4b..0d637b85540 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/DexcomPlugin.kt @@ -149,8 +149,9 @@ class DexcomPlugin @Inject constructor( glucoseValues += CgmSourceTransaction.TransactionGlucoseValue( timestamp = timestamp, value = glucoseValueBundle.getInt("glucoseValue").toDouble(), - noise = null, raw = null, + smoothed = null, + noise = null, trendArrow = GlucoseValue.TrendArrow.fromString(glucoseValueBundle.getString("trendArrow")!!), sourceSensor = sourceSensor ) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt index 92b24df2df4..a493c0e6e95 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/EversensePlugin.kt @@ -105,6 +105,7 @@ class EversensePlugin @Inject constructor( timestamp = glucoseTimestamps[i], value = glucoseLevels[i].toDouble(), raw = glucoseLevels[i].toDouble(), + smoothed = null, noise = null, trendArrow = GlucoseValue.TrendArrow.NONE, sourceSensor = GlucoseValue.SourceSensor.EVERSENSE diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt index 2daf641769d..4fd0ccc390b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlimpPlugin.kt @@ -65,6 +65,7 @@ class GlimpPlugin @Inject constructor( timestamp = inputData.getLong("myTimestamp", 0), value = inputData.getDouble("mySGV", 0.0), raw = inputData.getDouble("mySGV", 0.0), + smoothed = null, noise = null, trendArrow = GlucoseValue.TrendArrow.fromString(inputData.getString("myTrend")), sourceSensor = GlucoseValue.SourceSensor.GLIMP diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt index 12dabeff518..c7def902cd0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/GlunovoPlugin.kt @@ -123,6 +123,7 @@ class GlunovoPlugin @Inject constructor( timestamp = timestamp, value = value * Constants.MMOLL_TO_MGDL, raw = 0.0, + smoothed = null, noise = null, trendArrow = GlucoseValue.TrendArrow.NONE, sourceSensor = GlucoseValue.SourceSensor.GLUNOVO_NATIVE diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt index 1183c22fa7a..5142d849e1d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/IntelligoPlugin.kt @@ -134,6 +134,7 @@ class IntelligoPlugin @Inject constructor( timestamp = timestamp, value = value * Constants.MMOLL_TO_MGDL, raw = 0.0, + smoothed = null, noise = null, trendArrow = GlucoseValue.TrendArrow.NONE, sourceSensor = GlucoseValue.SourceSensor.INTELLIGO_NATIVE diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt index b21599a57fd..55ebb90896d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/MM640gPlugin.kt @@ -78,6 +78,7 @@ class MM640gPlugin @Inject constructor( timestamp = jsonObject.getLong("date"), value = jsonObject.getDouble("sgv"), raw = jsonObject.getDouble("sgv"), + smoothed = null, noise = null, trendArrow = GlucoseValue.TrendArrow.fromString(jsonObject.getString("direction")), sourceSensor = GlucoseValue.SourceSensor.MM_600_SERIES diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt index 8d8ba5ef8c1..37c39508539 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/NSClientSourcePlugin.kt @@ -104,8 +104,9 @@ class NSClientSourcePlugin @Inject constructor( return CgmSourceTransaction.TransactionGlucoseValue( timestamp = sgv.mills ?: return null, value = sgv.mgdl?.toDouble() ?: return null, - noise = null, raw = sgv.filtered?.toDouble() ?: sgv.mgdl?.toDouble(), + smoothed = null, + noise = null, trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction), nightscoutId = sgv.id, sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt index 2047be6e7a9..4c8292f5887 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/PoctechPlugin.kt @@ -72,6 +72,7 @@ class PoctechPlugin @Inject constructor( timestamp = json.getLong("date"), value = if (safeGetString(json, "units", Constants.MGDL) == "mmol/L") json.getDouble("current") * Constants.MMOLL_TO_MGDL else json.getDouble("current"), + smoothed = null, raw = json.getDouble("raw"), noise = null, trendArrow = GlucoseValue.TrendArrow.fromString(json.getString("direction")), diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt index 751c4463fbf..9b34557c2f2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt @@ -109,6 +109,7 @@ class RandomBgPlugin @Inject constructor( value = bgMgdl, raw = 0.0, noise = null, + smoothed = null, trendArrow = GlucoseValue.TrendArrow.NONE, sourceSensor = GlucoseValue.SourceSensor.RANDOM ) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt index 719357cf816..88de6a282d3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/TomatoPlugin.kt @@ -66,6 +66,7 @@ class TomatoPlugin @Inject constructor( value = inputData.getDouble("com.fanqies.tomatofn.Extras.BgEstimate", 0.0), raw = 0.0, noise = null, + smoothed = null, trendArrow = GlucoseValue.TrendArrow.NONE, sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_TOMATO ) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt index 4ca1f0eb013..64d9e9ef8cc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/XdripPlugin.kt @@ -83,6 +83,7 @@ class XdripPlugin @Inject constructor( timestamp = bundle.getLong(Intents.EXTRA_TIMESTAMP, 0), value = bundle.getDouble(Intents.EXTRA_BG_ESTIMATE, 0.0), raw = bundle.getDouble(Intents.EXTRA_RAW, 0.0), + smoothed = null, noise = null, trendArrow = GlucoseValue.TrendArrow.fromString(bundle.getString(Intents.EXTRA_BG_SLOPE_NAME)), sourceSensor = GlucoseValue.SourceSensor.fromString(bundle.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt index c6dee8a6608..ffe959f32fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt @@ -103,7 +103,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec //BG var bg = 0.0 if (useBG() == YES) { - bg = lastBG.valueToUnits(profileFunction.getUnits()) + bg = lastBG.valueToUnits(profileFunction.getUnits(), sp) } // COB val cob = diff --git a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBgDataWorker.kt b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBgDataWorker.kt index 04169682bb7..247c8f39e24 100644 --- a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBgDataWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBgDataWorker.kt @@ -5,7 +5,9 @@ import androidx.work.Worker import androidx.work.WorkerParameters import androidx.work.workDataOf import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.AppRepository +import info.nightscout.androidaps.extensions.rawOrSmoothed import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.Profile @@ -18,6 +20,7 @@ import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.sharedPreferences.SP import java.util.ArrayList import javax.inject.Inject @@ -29,6 +32,7 @@ class PrepareBgDataWorker( @Inject lateinit var dataWorkerStorage: DataWorkerStorage @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var rh: ResourceHelper + @Inject lateinit var sp: SP @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var repository: AppRepository @@ -45,14 +49,15 @@ class PrepareBgDataWorker( val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PrepareBgData? ?: return Result.failure(workDataOf("Error" to "missing input data")) + val useSmoothed = sp.getBoolean(R.string.key_use_data_smoothing, false) data.overviewData.maxBgValue = Double.MIN_VALUE data.overviewData.bgReadingsArray = repository.compatGetBgReadingsDataFromTime(data.overviewData.fromTime, data.overviewData.toTime, false).blockingGet() val bgListArray: MutableList = ArrayList() for (bg in data.overviewData.bgReadingsArray) { if (bg.timestamp < data.overviewData.fromTime || bg.timestamp > data.overviewData.toTime) continue - if (bg.value > data.overviewData.maxBgValue) data.overviewData.maxBgValue = bg.value - bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh)) + if (bg.rawOrSmoothed(useSmoothed) > data.overviewData.maxBgValue) data.overviewData.maxBgValue = bg.rawOrSmoothed(useSmoothed) + bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh, sp)) } bgListArray.sortWith { o1: DataPointWithLabelInterface, o2: DataPointWithLabelInterface -> o1.x.compareTo(o2.x) } data.overviewData.bgReadingGraphSeries = PointsWithLabelGraphSeries(Array(bgListArray.size) { i -> bgListArray[i] }) diff --git a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBucketedDataWorker.kt b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBucketedDataWorker.kt index 967d637f7da..94184c11a1e 100644 --- a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBucketedDataWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBucketedDataWorker.kt @@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Point import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject class PrepareBucketedDataWorker( @@ -25,6 +26,7 @@ class PrepareBucketedDataWorker( @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var rh: ResourceHelper @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var sp: SP init { (context.applicationContext as HasAndroidInjector).androidInjector().inject(this) @@ -48,7 +50,7 @@ class PrepareBucketedDataWorker( val bucketedListArray: MutableList = ArrayList() for (inMemoryGlucoseValue in bucketedData) { if (inMemoryGlucoseValue.timestamp < data.overviewData.fromTime || inMemoryGlucoseValue.timestamp > data.overviewData.toTime) continue - bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, profileFunction, rh)) + bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, profileFunction, rh, sp)) } bucketedListArray.sortWith { o1: DataPointWithLabelInterface, o2: DataPointWithLabelInterface -> o1.x.compareTo(o2.x) } data.overviewData.bucketedGraphSeries = PointsWithLabelGraphSeries(Array(bucketedListArray.size) { i -> bucketedListArray[i] }) diff --git a/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt b/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt index 2377af0fd3f..b4d60a474d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/workflow/PreparePredictionsWorker.kt @@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Point import info.nightscout.androidaps.receivers.DataWorkerStorage import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.T +import info.nightscout.shared.sharedPreferences.SP import java.util.Calendar import javax.inject.Inject import kotlin.math.ceil @@ -43,6 +44,7 @@ class PreparePredictionsWorker( @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var rh: ResourceHelper + @Inject lateinit var sp: SP init { (context.applicationContext as HasAndroidInjector).androidInjector().inject(this) @@ -83,7 +85,7 @@ class PreparePredictionsWorker( val bgListArray: MutableList = ArrayList() val predictions: MutableList? = apsResult?.predictions - ?.map { bg -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh) } + ?.map { bg -> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, rh, sp) } ?.toMutableList() if (predictions != null) { predictions.sortWith { o1: GlucoseValueDataPoint, o2: GlucoseValueDataPoint -> o1.x.compareTo(o2.x) } diff --git a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareTreatmentsDataWorker.kt b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareTreatmentsDataWorker.kt index 71e996c1d68..c51811f2793 100644 --- a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareTreatmentsDataWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareTreatmentsDataWorker.kt @@ -8,6 +8,7 @@ import dagger.android.HasAndroidInjector import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.TherapyEvent +import info.nightscout.androidaps.extensions.rawOrSmoothed import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.Profile @@ -22,6 +23,7 @@ import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.Translator +import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject class PrepareTreatmentsDataWorker( @@ -37,6 +39,7 @@ class PrepareTreatmentsDataWorker( @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var repository: AppRepository @Inject lateinit var defaultValueHelper: DefaultValueHelper + @Inject lateinit var sp: SP init { (context.applicationContext as HasAndroidInjector).androidInjector().inject(this) @@ -137,9 +140,10 @@ class PrepareTreatmentsDataWorker( overviewData.bgReadingsArray.let { bgReadingsArray -> for (reading in bgReadingsArray) { if (reading.timestamp > date) continue - return Profile.fromMgdlToUnits(reading.value, profileFunction.getUnits()) + return Profile.fromMgdlToUnits(reading.rawOrSmoothed(sp), profileFunction + .getUnits()) } - return if (bgReadingsArray.isNotEmpty()) Profile.fromMgdlToUnits(bgReadingsArray[0].value, profileFunction.getUnits()) + return if (bgReadingsArray.isNotEmpty()) Profile.fromMgdlToUnits(bgReadingsArray[0].rawOrSmoothed(sp), profileFunction.getUnits()) else Profile.fromMgdlToUnits(100.0, profileFunction.getUnits()) } } diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 9c1f9aaee52..eb51f1274f8 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -869,4 +869,11 @@ Очистка базы данных Вы хотите очистить базу данных?\nЭто удалит отслеживаемые изменения и данные старше 3 месяцев. Удалённые записи + + + use_data_smoothing + Использовать сглаженные показания данных ГК с сенсора. Рекомендуется в случе, если ваш сенсор не поддерживает сглаживание сам, а вы всё же хотите использовать SMB. + Сглаживать данные ГК с сенсора + Сглаживание значений сенсора включено. + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 14422b30e33..4e408a114b5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1062,4 +1062,10 @@ Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months. Cleared entries + + use_data_smoothing + Smooth and display incoming sensor data in the main chart. Recommended if your glucose source does not smooth sensor readings by itself and you would like to enable SMB always. + Smooth incoming glucose values + Smoothing of incoming sensor readings is enabled. + diff --git a/app/src/main/res/xml/pref_overview.xml b/app/src/main/res/xml/pref_overview.xml index bd9cda2bf99..fa2e3e6c828 100644 --- a/app/src/main/res/xml/pref_overview.xml +++ b/app/src/main/res/xml/pref_overview.xml @@ -14,6 +14,12 @@ android:summary="@string/keep_screen_on_summary" android:title="@string/keep_screen_on_title" /> + + diff --git a/core/src/main/java/info/nightscout/androidaps/data/InMemoryGlucoseValue.kt b/core/src/main/java/info/nightscout/androidaps/data/InMemoryGlucoseValue.kt index 00a89d48dbf..1fd360a5c11 100644 --- a/core/src/main/java/info/nightscout/androidaps/data/InMemoryGlucoseValue.kt +++ b/core/src/main/java/info/nightscout/androidaps/data/InMemoryGlucoseValue.kt @@ -1,9 +1,19 @@ package info.nightscout.androidaps.data +import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.entities.GlucoseValue +import info.nightscout.shared.sharedPreferences.SP -class InMemoryGlucoseValue constructor(var timestamp: Long = 0L, var value: Double = 0.0, var interpolated: Boolean = false) { +class InMemoryGlucoseValue constructor(var timestamp: Long = 0L, var value: Double = 0.0, var smoothed: Double? = null, var interpolated: Boolean = false) { - constructor(gv: GlucoseValue) : this(gv.timestamp, gv.value) + constructor(gv: GlucoseValue) : this(gv.timestamp, gv.value, gv.smoothed) // var generated : value doesn't correspond to real value with timestamp close to real BG + private fun useDataSmoothing(sp: SP): Boolean { + return sp.getBoolean(R.string.key_use_data_smoothing, false) + } + + fun rawOrSmoothed(sp: SP): Double { + if (useDataSmoothing(sp)) return smoothed ?: value + else return value + } } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/extensions/GlucoseValueExtension.kt b/core/src/main/java/info/nightscout/androidaps/extensions/GlucoseValueExtension.kt index a74fdff40b7..06aac714af5 100644 --- a/core/src/main/java/info/nightscout/androidaps/extensions/GlucoseValueExtension.kt +++ b/core/src/main/java/info/nightscout/androidaps/extensions/GlucoseValueExtension.kt @@ -1,19 +1,35 @@ package info.nightscout.androidaps.extensions import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.shared.sharedPreferences.SP import org.json.JSONObject -fun GlucoseValue.valueToUnits(units: GlucoseUnit): Double = - if (units == GlucoseUnit.MGDL) value - else value * Constants.MGDL_TO_MMOLL +fun useDataSmoothing(sp: SP): Boolean { + return sp.getBoolean(R.string.key_use_data_smoothing, false) +} -fun GlucoseValue.valueToUnitsString(units: GlucoseUnit): String = - if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(value) - else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL) +fun GlucoseValue.rawOrSmoothed(sp: SP): Double { + if (useDataSmoothing(sp)) return smoothed ?: value + else return value +} + +fun GlucoseValue.rawOrSmoothed(useSmoothed: Boolean): Double { + if (useSmoothed) return smoothed ?: value + else return value +} + +fun GlucoseValue.valueToUnits(units: GlucoseUnit, sp: SP): Double = + if (units == GlucoseUnit.MGDL) rawOrSmoothed(sp) + else rawOrSmoothed(sp) * Constants.MGDL_TO_MMOLL + +fun GlucoseValue.valueToUnitsString(units: GlucoseUnit, sp: SP): String = + if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(rawOrSmoothed(sp)) + else DecimalFormatter.to1Decimal(rawOrSmoothed(sp) * Constants.MGDL_TO_MMOLL) fun GlucoseValue.toJson(isAdd : Boolean, dateUtil: DateUtil): JSONObject = JSONObject() diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt index 010dea92250..de9773bf60c 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt @@ -198,6 +198,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) { raw = 0.0, noise = 0.0, value = iob.getInt(i).toDouble(), + smoothed = iob.getInt(i).toDouble(), timestamp = startTime + i * 5 * 60 * 1000L, sourceSensor = GlucoseValue.SourceSensor.IOB_PREDICTION, trendArrow = GlucoseValue.TrendArrow.NONE @@ -212,6 +213,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) { raw = 0.0, noise = 0.0, value = iob.getInt(i).toDouble(), + smoothed = iob.getInt(i).toDouble(), timestamp = startTime + i * 5 * 60 * 1000L, sourceSensor = GlucoseValue.SourceSensor.A_COB_PREDICTION, trendArrow = GlucoseValue.TrendArrow.NONE @@ -226,6 +228,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) { raw = 0.0, noise = 0.0, value = iob.getInt(i).toDouble(), + smoothed = iob.getInt(i).toDouble(), timestamp = startTime + i * 5 * 60 * 1000L, sourceSensor = GlucoseValue.SourceSensor.COB_PREDICTION, trendArrow = GlucoseValue.TrendArrow.NONE @@ -240,6 +243,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) { raw = 0.0, noise = 0.0, value = iob.getInt(i).toDouble(), + smoothed = iob.getInt(i).toDouble(), timestamp = startTime + i * 5 * 60 * 1000L, sourceSensor = GlucoseValue.SourceSensor.UAM_PREDICTION, trendArrow = GlucoseValue.TrendArrow.NONE @@ -254,6 +258,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) { raw = 0.0, noise = 0.0, value = iob.getInt(i).toDouble(), + smoothed = iob.getInt(i).toDouble(), timestamp = startTime + i * 5 * 60 * 1000L, sourceSensor = GlucoseValue.SourceSensor.ZT_PREDICTION, trendArrow = GlucoseValue.TrendArrow.NONE diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt index 0682f3646eb..1ade60b3dd9 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt @@ -126,12 +126,12 @@ class OverviewData @Inject constructor( val isLow: Boolean get() = lastBg?.let { lastBg -> - lastBg.valueToUnits(profileFunction.getUnits()) < defaultValueHelper.determineLowLine() + lastBg.valueToUnits(profileFunction.getUnits(), sp) < defaultValueHelper.determineLowLine() } ?: false val isHigh: Boolean get() = lastBg?.let { lastBg -> - lastBg.valueToUnits(profileFunction.getUnits()) > defaultValueHelper.determineHighLine() + lastBg.valueToUnits(profileFunction.getUnits(), sp) > defaultValueHelper.determineHighLine() } ?: false @ColorInt diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt index af527dec052..5c06eb6228a 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/GlucoseValueDataPoint.kt @@ -4,27 +4,30 @@ import android.content.Context import info.nightscout.androidaps.Constants import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.entities.GlucoseValue +import info.nightscout.androidaps.extensions.rawOrSmoothed import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.sharedPreferences.SP import info.nightscout.androidaps.utils.DefaultValueHelper class GlucoseValueDataPoint( val data: GlucoseValue, private val defaultValueHelper: DefaultValueHelper, private val profileFunction: ProfileFunction, - private val rh: ResourceHelper + private val rh: ResourceHelper, + private val sp: SP ) : DataPointWithLabelInterface { fun valueToUnits(units: GlucoseUnit): Double = - if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL + if (units == GlucoseUnit.MGDL) data.rawOrSmoothed(sp) else data.rawOrSmoothed(sp) * Constants.MGDL_TO_MMOLL override fun getX(): Double = data.timestamp.toDouble() override fun getY(): Double = valueToUnits(profileFunction.getUnits()) override fun setY(y: Double) {} - override val label: String = Profile.toCurrentUnitsString(profileFunction, data.value) + override val label: String = Profile.toCurrentUnitsString(profileFunction, data.rawOrSmoothed(sp)) override val duration = 0L override val shape get() = if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION else PointsWithLabelGraphSeries.Shape.BG override val size = 1f diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt index 712ef228956..1dac43f495a 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/InMemoryGlucoseValueDataPoint.kt @@ -7,15 +7,18 @@ import info.nightscout.androidaps.data.InMemoryGlucoseValue import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.sharedPreferences.SP class InMemoryGlucoseValueDataPoint( val data: InMemoryGlucoseValue, private val profileFunction: ProfileFunction, - private val rh: ResourceHelper + private val rh: ResourceHelper, + private val sp: SP ) : DataPointWithLabelInterface { fun valueToUnits(units: GlucoseUnit): Double = - if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL + if (units == GlucoseUnit.MGDL) data.rawOrSmoothed(sp) + else data.rawOrSmoothed(sp) * Constants.MGDL_TO_MMOLL override fun getX(): Double = data.timestamp.toDouble() override fun getY(): Double = valueToUnits(profileFunction.getUnits()) diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensDataStore.kt b/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensDataStore.kt index f57d71315b8..a8b7872cd7c 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensDataStore.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensDataStore.kt @@ -3,9 +3,11 @@ package info.nightscout.androidaps.plugins.iob.iobCobCalculator import androidx.collection.LongSparseArray import androidx.collection.size import info.nightscout.androidaps.annotations.OpenForTesting +import info.nightscout.androidaps.core.R import info.nightscout.androidaps.data.InMemoryGlucoseValue import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.GlucoseValue +import info.nightscout.androidaps.extensions.rawOrSmoothed import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBus @@ -13,11 +15,12 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T +import info.nightscout.shared.sharedPreferences.SP import kotlin.math.abs import kotlin.math.roundToLong @OpenForTesting -class AutosensDataStore { +class AutosensDataStore (val sp: SP) { private val dataLock = Any() var lastUsed5minCalculation: Boolean? = null // true if used 5min bucketed data @@ -39,7 +42,7 @@ class AutosensDataStore { @Synchronized get fun clone(): AutosensDataStore = - AutosensDataStore().also { + AutosensDataStore(sp).also { synchronized(dataLock) { it.bgReadings = this.bgReadings.toMutableList() it.autosensDataTable = LongSparseArray(this.autosensDataTable.size).apply { putAll(this@AutosensDataStore.autosensDataTable) } @@ -236,6 +239,7 @@ class AutosensDataStore { bucketedData = null return } + val useBgSmoothing = sp.getBoolean(R.string.key_use_data_smoothing, false) val newBucketedData = ArrayList() var currentTime = bgReadings[0].timestamp - bgReadings[0].timestamp % T.mins(5).msecs() val adjustedTime = adjustToReferenceTime(currentTime) @@ -251,10 +255,13 @@ class AutosensDataStore { if (older.timestamp == newer.timestamp) { // direct hit newBucketedData.add(InMemoryGlucoseValue(newer)) } else { - val bgDelta = newer.value - older.value + val bgDeltaRaw = newer.value - older.value + val bgDeltaSmoothed = newer.rawOrSmoothed(useBgSmoothing) - older.rawOrSmoothed(useBgSmoothing) val timeDiffToNew = newer.timestamp - currentTime - val currentBg = newer.value - timeDiffToNew.toDouble() / (newer.timestamp - older.timestamp) * bgDelta - val newBgReading = InMemoryGlucoseValue(currentTime, currentBg.roundToLong().toDouble(), true) + val currentBgRaw = newer.value - timeDiffToNew.toDouble() / (newer.timestamp - older.timestamp) * bgDeltaRaw + val currentBgSmoothed = newer.rawOrSmoothed(useBgSmoothing) - timeDiffToNew.toDouble() / (newer.timestamp - older.timestamp) * bgDeltaSmoothed + + val newBgReading = InMemoryGlucoseValue(currentTime, currentBgRaw.roundToLong().toDouble(), currentBgSmoothed.roundToLong().toDouble(),true) newBucketedData.add(newBgReading) //log.debug("BG: " + newBgReading.value + " (" + new Date(newBgReading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")"); } @@ -269,6 +276,7 @@ class AutosensDataStore { return } val bData: MutableList = ArrayList() + val useBgSmoothing = sp.getBoolean(R.string.key_use_data_smoothing, false) bData.add(InMemoryGlucoseValue(bgReadings[0])) aapsLogger.debug(LTag.AUTOSENS) { "Adding. bgTime: ${dateUtil.toISOString(bgReadings[0].timestamp)} lastBgTime: none-first-value ${bgReadings[0]}" } var j = 0 @@ -280,39 +288,44 @@ class AutosensDataStore { when { abs(elapsedMinutes) > 8 -> { // interpolate missing data points - var lastBg = bgReadings[i - 1].value + var lastBgRaw = bgReadings[i - 1].value + var lastBgSmoothed = bgReadings[i - 1].rawOrSmoothed(useBgSmoothing) elapsedMinutes = abs(elapsedMinutes) //console.error(elapsed_minutes); var nextBgTime: Long while (elapsedMinutes > 5) { nextBgTime = lastBgTime - 5 * 60 * 1000 j++ - val gapDelta = bgReadings[i].value - lastBg + val gapDeltaRaw = bgReadings[i].value - lastBgRaw + val gapDeltaSmoothed = bgReadings[i].value - lastBgSmoothed //console.error(gapDelta, lastBg, elapsed_minutes); - val nextBg = lastBg + 5.0 / elapsedMinutes * gapDelta - val newBgReading = InMemoryGlucoseValue(nextBgTime, nextBg.roundToLong().toDouble(), true) + val nextBgRaw = lastBgRaw + 5.0 / elapsedMinutes * gapDeltaRaw + val nextBgSmoothed = lastBgSmoothed + 5.0 / elapsedMinutes * gapDeltaSmoothed + val newBgReading = InMemoryGlucoseValue(nextBgTime, nextBgRaw.roundToLong().toDouble(), nextBgSmoothed.roundToLong().toDouble(), true) //console.error("Interpolated", bData[j]); bData.add(newBgReading) aapsLogger.debug(LTag.AUTOSENS) { "Adding. bgTime: ${dateUtil.toISOString(bgTime)} lastBgTime: ${dateUtil.toISOString(lastBgTime)} $newBgReading" } elapsedMinutes -= 5 - lastBg = nextBg + lastBgRaw = nextBgRaw + lastBgSmoothed = nextBgSmoothed lastBgTime = nextBgTime } j++ - val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value) + val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value, bgReadings[i].smoothed) bData.add(newBgReading) aapsLogger.debug(LTag.AUTOSENS) { "Adding. bgTime: ${dateUtil.toISOString(bgTime)} lastBgTime: ${dateUtil.toISOString(lastBgTime)} $newBgReading" } } abs(elapsedMinutes) > 2 -> { j++ - val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value) + val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value, bgReadings[i].smoothed) bData.add(newBgReading) aapsLogger.debug(LTag.AUTOSENS) { "Adding. bgTime: ${dateUtil.toISOString(bgTime)} lastBgTime: ${dateUtil.toISOString(lastBgTime)} $newBgReading" } } else -> { bData[j].value = (bData[j].value + bgReadings[i].value) / 2 + bData[j].smoothed = (bData[j].rawOrSmoothed(sp) + bgReadings[i].rawOrSmoothed(useBgSmoothing)) / 2 //log.error("***** Average"); } } @@ -354,4 +367,4 @@ class AutosensDataStore { } return if (count != 0) sum / count else 0.0 } -} +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatusProvider.kt b/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatusProvider.kt index f722383f5f5..b94f3be0291 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatusProvider.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatusProvider.kt @@ -1,10 +1,13 @@ package info.nightscout.androidaps.plugins.iob.iobCobCalculator import dagger.Reusable +import info.nightscout.androidaps.extensions.rawOrSmoothed +import info.nightscout.androidaps.extensions.useDataSmoothing import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.shared.sharedPreferences.SP import java.util.* import javax.inject.Inject import kotlin.math.roundToLong @@ -13,7 +16,8 @@ import kotlin.math.roundToLong class GlucoseStatusProvider @Inject constructor( private val aapsLogger: AAPSLogger, private val iobCobCalculator: IobCobCalculator, - private val dateUtil: DateUtil + private val dateUtil: DateUtil, + private val sp: SP ) { val glucoseStatusData: GlucoseStatus? @@ -50,7 +54,7 @@ class GlucoseStatusProvider @Inject constructor( val longDeltas = ArrayList() // Use the latest sgv value in the now calculations - nowValueList.add(now.value) + nowValueList.add(now.rawOrSmoothed(sp)) for (i in 1 until sizeRecords) { if (data[i].value > 38) { val then = data[i] @@ -58,15 +62,15 @@ class GlucoseStatusProvider @Inject constructor( val minutesAgo = ((nowDate - thenDate) / (1000.0 * 60)).roundToLong() // multiply by 5 to get the same units as delta, i.e. mg/dL/5m - change = now.value - then.value + change = now.rawOrSmoothed(sp) - then.rawOrSmoothed(sp) val avgDel = change / minutesAgo * 5 aapsLogger.debug(LTag.GLUCOSE, "$then minutesAgo=$minutesAgo avgDelta=$avgDel") // use the average of all data points in the last 2.5m for all further "now" calculations if (0 < minutesAgo && minutesAgo < 2.5) { // Keep and average all values within the last 2.5 minutes - nowValueList.add(then.value) - now.value = average(nowValueList) + nowValueList.add(then.rawOrSmoothed(sp)) + if (useDataSmoothing(sp)) now.smoothed = average(nowValueList) else now.value = average(nowValueList) // short_deltas are calculated from everything ~5-15 minutes ago } else if (2.5 < minutesAgo && minutesAgo < 17.5) { //console.error(minutesAgo, avgDelta); @@ -91,7 +95,7 @@ class GlucoseStatusProvider @Inject constructor( average(lastDeltas) } return GlucoseStatus( - glucose = now.value, + glucose = now.rawOrSmoothed(sp), date = nowDate, noise = 0.0, //for now set to nothing as not all CGMs report noise shortAvgDelta = shortAverageDelta, diff --git a/core/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt b/core/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt index 024de884a55..d8029e2a89f 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt @@ -4,14 +4,17 @@ import info.nightscout.androidaps.core.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.entities.GlucoseValue.TrendArrow.* +import info.nightscout.androidaps.extensions.rawOrSmoothed import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject import javax.inject.Singleton @Singleton class TrendCalculator @Inject constructor( private val repository: AppRepository, - private val rh: ResourceHelper + private val rh: ResourceHelper, + private val sp: SP ) { fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow = @@ -47,7 +50,7 @@ class TrendCalculator @Inject constructor( // Avoid division by 0 val slope = if (current.timestamp == previous.timestamp) 0.0 - else (previous.value - current.value) / (previous.timestamp - current.timestamp) + else (previous.rawOrSmoothed(sp) - current.rawOrSmoothed(sp)) / (previous.timestamp - current.timestamp) val slopeByMinute = slope * 60000 diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index e3dffa9a066..e9df8d1815f 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -640,6 +640,7 @@ Error during last Autotune run Another run of Autotune is detected, run cancelled Application needs bluetooth permission + use_data_smoothing Missing SMS permission diff --git a/database/schemas/info.nightscout.androidaps.database.AppDatabase/22.json b/database/schemas/info.nightscout.androidaps.database.AppDatabase/22.json index 93af25de947..8a26f81a42d 100644 --- a/database/schemas/info.nightscout.androidaps.database.AppDatabase/22.json +++ b/database/schemas/info.nightscout.androidaps.database.AppDatabase/22.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 22, - "identityHash": "09121464fb795b3c37bb1c2c2c3ea481", + "identityHash": "9efbf222b2454f2d47bf179c65df24c0", "entities": [ { "tableName": "apsResults", @@ -166,6 +166,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResults_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -174,6 +175,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResults_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -193,7 +195,7 @@ }, { "tableName": "boluses", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `amount` REAL NOT NULL, `type` TEXT NOT NULL, `notes` TEXT, `isBasalInsulin` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT, `insulinEndTime` INTEGER, `peak` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `amount` REAL NOT NULL, `type` TEXT NOT NULL, `isBasalInsulin` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT, `insulinEndTime` INTEGER, `peak` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "fields": [ { "fieldPath": "id", @@ -249,12 +251,6 @@ "affinity": "TEXT", "notNull": true }, - { - "fieldPath": "notes", - "columnName": "notes", - "affinity": "TEXT", - "notNull": false - }, { "fieldPath": "isBasalInsulin", "columnName": "isBasalInsulin", @@ -341,6 +337,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -349,6 +346,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -357,6 +355,7 @@ "columnNames": [ "temporaryId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_temporaryId` ON `${TABLE_NAME}` (`temporaryId`)" }, { @@ -365,6 +364,7 @@ "columnNames": [ "pumpId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_pumpId` ON `${TABLE_NAME}` (`pumpId`)" }, { @@ -373,6 +373,7 @@ "columnNames": [ "pumpSerial" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" }, { @@ -381,6 +382,7 @@ "columnNames": [ "pumpType" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_pumpType` ON `${TABLE_NAME}` (`pumpType`)" }, { @@ -389,6 +391,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -397,6 +400,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -696,6 +700,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -704,6 +709,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_timestamp` ON `${TABLE_NAME}` (`timestamp`)" }, { @@ -712,6 +718,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -720,6 +727,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_isValid` ON `${TABLE_NAME}` (`isValid`)" } ], @@ -739,7 +747,7 @@ }, { "tableName": "carbs", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `notes` TEXT, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "fields": [ { "fieldPath": "id", @@ -795,12 +803,6 @@ "affinity": "REAL", "notNull": true }, - { - "fieldPath": "notes", - "columnName": "notes", - "affinity": "TEXT", - "notNull": false - }, { "fieldPath": "interfaceIDs_backing.nightscoutSystemId", "columnName": "nightscoutSystemId", @@ -863,6 +865,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -871,6 +874,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -879,6 +883,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -887,6 +892,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -895,6 +901,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -1104,6 +1111,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -1112,6 +1120,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -1120,6 +1129,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_timestamp` ON `${TABLE_NAME}` (`timestamp`)" }, { @@ -1128,6 +1138,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_isValid` ON `${TABLE_NAME}` (`isValid`)" } ], @@ -1271,6 +1282,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -1279,6 +1291,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -1287,6 +1300,7 @@ "columnNames": [ "endId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_endId` ON `${TABLE_NAME}` (`endId`)" }, { @@ -1295,6 +1309,7 @@ "columnNames": [ "pumpSerial" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" }, { @@ -1303,6 +1318,7 @@ "columnNames": [ "pumpId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_pumpId` ON `${TABLE_NAME}` (`pumpId`)" }, { @@ -1311,6 +1327,7 @@ "columnNames": [ "pumpType" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_pumpType` ON `${TABLE_NAME}` (`pumpType`)" }, { @@ -1319,6 +1336,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -1327,6 +1345,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -1346,7 +1365,7 @@ }, { "tableName": "glucoseValues", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `raw` REAL, `value` REAL NOT NULL, `trendArrow` TEXT NOT NULL, `noise` REAL, `sourceSensor` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `glucoseValues`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `raw` REAL, `value` REAL NOT NULL, `smoothed` REAL, `trendArrow` TEXT NOT NULL, `noise` REAL, `sourceSensor` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `glucoseValues`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "fields": [ { "fieldPath": "id", @@ -1402,6 +1421,12 @@ "affinity": "REAL", "notNull": true }, + { + "fieldPath": "smoothed", + "columnName": "smoothed", + "affinity": "REAL", + "notNull": false + }, { "fieldPath": "trendArrow", "columnName": "trendArrow", @@ -1482,6 +1507,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -1490,6 +1516,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -1498,6 +1525,7 @@ "columnNames": [ "sourceSensor" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_sourceSensor` ON `${TABLE_NAME}` (`sourceSensor`)" }, { @@ -1506,6 +1534,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -1514,6 +1543,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -1711,6 +1741,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -1719,6 +1750,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_timestamp` ON `${TABLE_NAME}` (`timestamp`)" }, { @@ -1727,6 +1759,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -1735,6 +1768,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -1743,6 +1777,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" } ], @@ -1892,6 +1927,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -1900,6 +1936,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -1908,6 +1945,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -1916,6 +1954,7 @@ "columnNames": [ "pumpType" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_pumpType` ON `${TABLE_NAME}` (`pumpType`)" }, { @@ -1924,6 +1963,7 @@ "columnNames": [ "endId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_endId` ON `${TABLE_NAME}` (`endId`)" }, { @@ -1932,6 +1972,7 @@ "columnNames": [ "pumpSerial" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" }, { @@ -1940,6 +1981,7 @@ "columnNames": [ "temporaryId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_temporaryId` ON `${TABLE_NAME}` (`temporaryId`)" }, { @@ -1948,6 +1990,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -1956,6 +1999,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -2105,6 +2149,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -2113,6 +2158,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -2121,6 +2167,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -2129,6 +2176,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -2137,6 +2185,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -2304,6 +2353,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -2312,6 +2362,7 @@ "columnNames": [ "type" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_type` ON `${TABLE_NAME}` (`type`)" }, { @@ -2320,6 +2371,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -2328,6 +2380,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -2336,6 +2389,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -2344,6 +2398,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -2493,6 +2548,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -2501,6 +2557,7 @@ "columnNames": [ "pumpId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_pumpId` ON `${TABLE_NAME}` (`pumpId`)" }, { @@ -2509,6 +2566,7 @@ "columnNames": [ "pumpType" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_pumpType` ON `${TABLE_NAME}` (`pumpType`)" }, { @@ -2517,6 +2575,7 @@ "columnNames": [ "pumpSerial" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" }, { @@ -2525,6 +2584,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -2533,6 +2593,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -2541,6 +2602,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -2672,6 +2734,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -2680,6 +2743,7 @@ "columnNames": [ "apsResultId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_apsResultId` ON `${TABLE_NAME}` (`apsResultId`)" }, { @@ -2688,6 +2752,7 @@ "columnNames": [ "smbId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_smbId` ON `${TABLE_NAME}` (`smbId`)" }, { @@ -2696,6 +2761,7 @@ "columnNames": [ "tbrId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_tbrId` ON `${TABLE_NAME}` (`tbrId`)" } ], @@ -2854,6 +2920,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_multiwaveBolusLinks_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -2862,6 +2929,7 @@ "columnNames": [ "bolusId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_multiwaveBolusLinks_bolusId` ON `${TABLE_NAME}` (`bolusId`)" }, { @@ -2870,6 +2938,7 @@ "columnNames": [ "extendedBolusId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_multiwaveBolusLinks_extendedBolusId` ON `${TABLE_NAME}` (`extendedBolusId`)" } ], @@ -3069,6 +3138,7 @@ "columnNames": [ "source" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_userEntry_source` ON `${TABLE_NAME}` (`source`)" }, { @@ -3077,6 +3147,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_userEntry_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -3238,6 +3309,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -3246,6 +3318,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -3254,6 +3327,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -3262,6 +3336,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_isValid` ON `${TABLE_NAME}` (`isValid`)" } ], @@ -3405,6 +3480,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_deviceStatus_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -3413,6 +3489,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_deviceStatus_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -3421,6 +3498,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_deviceStatus_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -3546,6 +3624,7 @@ "columnNames": [ "id" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_id` ON `${TABLE_NAME}` (`id`)" }, { @@ -3554,6 +3633,7 @@ "columnNames": [ "isValid" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_isValid` ON `${TABLE_NAME}` (`isValid`)" }, { @@ -3562,6 +3642,7 @@ "columnNames": [ "nightscoutId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" }, { @@ -3570,6 +3651,7 @@ "columnNames": [ "referenceId" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_referenceId` ON `${TABLE_NAME}` (`referenceId`)" }, { @@ -3578,6 +3660,7 @@ "columnNames": [ "timestamp" ], + "orders": [], "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_timestamp` ON `${TABLE_NAME}` (`timestamp`)" } ], @@ -3599,7 +3682,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '09121464fb795b3c37bb1c2c2c3ea481')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9efbf222b2454f2d47bf179c65df24c0')" ] } } \ No newline at end of file diff --git a/database/schemas/info.nightscout.androidaps.database.AppDatabase/23.json b/database/schemas/info.nightscout.androidaps.database.AppDatabase/23.json new file mode 100644 index 00000000000..d7c38d211ad --- /dev/null +++ b/database/schemas/info.nightscout.androidaps.database.AppDatabase/23.json @@ -0,0 +1,3700 @@ +{ + "formatVersion": 1, + "database": { + "version": 23, + "identityHash": "dda7fa990182c143f1b89139d96e40f7", + "entities": [ + { + "tableName": "apsResults", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `algorithm` TEXT NOT NULL, `glucoseStatusJson` TEXT NOT NULL, `currentTempJson` TEXT NOT NULL, `iobDataJson` TEXT NOT NULL, `profileJson` TEXT NOT NULL, `autosensDataJson` TEXT, `mealDataJson` TEXT NOT NULL, `isMicroBolusAllowed` INTEGER, `resultJson` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `apsResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "algorithm", + "columnName": "algorithm", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "glucoseStatusJson", + "columnName": "glucoseStatusJson", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currentTempJson", + "columnName": "currentTempJson", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "iobDataJson", + "columnName": "iobDataJson", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "profileJson", + "columnName": "profileJson", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "autosensDataJson", + "columnName": "autosensDataJson", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mealDataJson", + "columnName": "mealDataJson", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isMicroBolusAllowed", + "columnName": "isMicroBolusAllowed", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "resultJson", + "columnName": "resultJson", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_apsResults_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResults_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_apsResults_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResults_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "apsResults", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "boluses", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `amount` REAL NOT NULL, `type` TEXT NOT NULL, `notes` TEXT, `isBasalInsulin` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT, `insulinEndTime` INTEGER, `peak` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "notes", + "columnName": "notes", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isBasalInsulin", + "columnName": "isBasalInsulin", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "insulinConfiguration.insulinLabel", + "columnName": "insulinLabel", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "insulinConfiguration.insulinEndTime", + "columnName": "insulinEndTime", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "insulinConfiguration.peak", + "columnName": "peak", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_boluses_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_boluses_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_boluses_temporaryId", + "unique": false, + "columnNames": [ + "temporaryId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_temporaryId` ON `${TABLE_NAME}` (`temporaryId`)" + }, + { + "name": "index_boluses_pumpId", + "unique": false, + "columnNames": [ + "pumpId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_pumpId` ON `${TABLE_NAME}` (`pumpId`)" + }, + { + "name": "index_boluses_pumpSerial", + "unique": false, + "columnNames": [ + "pumpSerial" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" + }, + { + "name": "index_boluses_pumpType", + "unique": false, + "columnNames": [ + "pumpType" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_pumpType` ON `${TABLE_NAME}` (`pumpType`)" + }, + { + "name": "index_boluses_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_boluses_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_boluses_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "boluses", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "bolusCalculatorResults", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `targetBGLow` REAL NOT NULL, `targetBGHigh` REAL NOT NULL, `isf` REAL NOT NULL, `ic` REAL NOT NULL, `bolusIOB` REAL NOT NULL, `wasBolusIOBUsed` INTEGER NOT NULL, `basalIOB` REAL NOT NULL, `wasBasalIOBUsed` INTEGER NOT NULL, `glucoseValue` REAL NOT NULL, `wasGlucoseUsed` INTEGER NOT NULL, `glucoseDifference` REAL NOT NULL, `glucoseInsulin` REAL NOT NULL, `glucoseTrend` REAL NOT NULL, `wasTrendUsed` INTEGER NOT NULL, `trendInsulin` REAL NOT NULL, `cob` REAL NOT NULL, `wasCOBUsed` INTEGER NOT NULL, `cobInsulin` REAL NOT NULL, `carbs` REAL NOT NULL, `wereCarbsUsed` INTEGER NOT NULL, `carbsInsulin` REAL NOT NULL, `otherCorrection` REAL NOT NULL, `wasSuperbolusUsed` INTEGER NOT NULL, `superbolusInsulin` REAL NOT NULL, `wasTempTargetUsed` INTEGER NOT NULL, `totalInsulin` REAL NOT NULL, `percentageCorrection` INTEGER NOT NULL, `profileName` TEXT NOT NULL, `note` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "targetBGLow", + "columnName": "targetBGLow", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "targetBGHigh", + "columnName": "targetBGHigh", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "isf", + "columnName": "isf", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "ic", + "columnName": "ic", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "bolusIOB", + "columnName": "bolusIOB", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wasBolusIOBUsed", + "columnName": "wasBolusIOBUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "basalIOB", + "columnName": "basalIOB", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wasBasalIOBUsed", + "columnName": "wasBasalIOBUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "glucoseValue", + "columnName": "glucoseValue", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wasGlucoseUsed", + "columnName": "wasGlucoseUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "glucoseDifference", + "columnName": "glucoseDifference", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "glucoseInsulin", + "columnName": "glucoseInsulin", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "glucoseTrend", + "columnName": "glucoseTrend", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wasTrendUsed", + "columnName": "wasTrendUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "trendInsulin", + "columnName": "trendInsulin", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "cob", + "columnName": "cob", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wasCOBUsed", + "columnName": "wasCOBUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "cobInsulin", + "columnName": "cobInsulin", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "carbs", + "columnName": "carbs", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wereCarbsUsed", + "columnName": "wereCarbsUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "carbsInsulin", + "columnName": "carbsInsulin", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "otherCorrection", + "columnName": "otherCorrection", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wasSuperbolusUsed", + "columnName": "wasSuperbolusUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "superbolusInsulin", + "columnName": "superbolusInsulin", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "wasTempTargetUsed", + "columnName": "wasTempTargetUsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "totalInsulin", + "columnName": "totalInsulin", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "percentageCorrection", + "columnName": "percentageCorrection", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "profileName", + "columnName": "profileName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "note", + "columnName": "note", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_bolusCalculatorResults_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_bolusCalculatorResults_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + }, + { + "name": "index_bolusCalculatorResults_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_bolusCalculatorResults_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_isValid` ON `${TABLE_NAME}` (`isValid`)" + } + ], + "foreignKeys": [ + { + "table": "bolusCalculatorResults", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "carbs", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `notes` TEXT, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "notes", + "columnName": "notes", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_carbs_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_carbs_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_carbs_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_carbs_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_carbs_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_carbs_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "carbs", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "effectiveProfileSwitches", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `basalBlocks` TEXT NOT NULL, `isfBlocks` TEXT NOT NULL, `icBlocks` TEXT NOT NULL, `targetBlocks` TEXT NOT NULL, `glucoseUnit` TEXT NOT NULL, `originalProfileName` TEXT NOT NULL, `originalCustomizedName` TEXT NOT NULL, `originalTimeshift` INTEGER NOT NULL, `originalPercentage` INTEGER NOT NULL, `originalDuration` INTEGER NOT NULL, `originalEnd` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT NOT NULL, `insulinEndTime` INTEGER NOT NULL, `peak` INTEGER NOT NULL, FOREIGN KEY(`referenceId`) REFERENCES `effectiveProfileSwitches`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "basalBlocks", + "columnName": "basalBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isfBlocks", + "columnName": "isfBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icBlocks", + "columnName": "icBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "targetBlocks", + "columnName": "targetBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "glucoseUnit", + "columnName": "glucoseUnit", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "originalProfileName", + "columnName": "originalProfileName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "originalCustomizedName", + "columnName": "originalCustomizedName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "originalTimeshift", + "columnName": "originalTimeshift", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "originalPercentage", + "columnName": "originalPercentage", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "originalDuration", + "columnName": "originalDuration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "originalEnd", + "columnName": "originalEnd", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "insulinConfiguration.insulinLabel", + "columnName": "insulinLabel", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "insulinConfiguration.insulinEndTime", + "columnName": "insulinEndTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "insulinConfiguration.peak", + "columnName": "peak", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_effectiveProfileSwitches_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_effectiveProfileSwitches_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_effectiveProfileSwitches_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + }, + { + "name": "index_effectiveProfileSwitches_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_effectiveProfileSwitches_isValid` ON `${TABLE_NAME}` (`isValid`)" + } + ], + "foreignKeys": [ + { + "table": "effectiveProfileSwitches", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "extendedBoluses", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `isEmulatingTempBasal` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `extendedBoluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "isEmulatingTempBasal", + "columnName": "isEmulatingTempBasal", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_extendedBoluses_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_extendedBoluses_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_extendedBoluses_endId", + "unique": false, + "columnNames": [ + "endId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_endId` ON `${TABLE_NAME}` (`endId`)" + }, + { + "name": "index_extendedBoluses_pumpSerial", + "unique": false, + "columnNames": [ + "pumpSerial" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" + }, + { + "name": "index_extendedBoluses_pumpId", + "unique": false, + "columnNames": [ + "pumpId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_pumpId` ON `${TABLE_NAME}` (`pumpId`)" + }, + { + "name": "index_extendedBoluses_pumpType", + "unique": false, + "columnNames": [ + "pumpType" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_pumpType` ON `${TABLE_NAME}` (`pumpType`)" + }, + { + "name": "index_extendedBoluses_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_extendedBoluses_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_extendedBoluses_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "extendedBoluses", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "glucoseValues", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `raw` REAL, `value` REAL NOT NULL, `smoothed` REAL, `trendArrow` TEXT NOT NULL, `noise` REAL, `sourceSensor` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `glucoseValues`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "raw", + "columnName": "raw", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "smoothed", + "columnName": "smoothed", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "trendArrow", + "columnName": "trendArrow", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "noise", + "columnName": "noise", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "sourceSensor", + "columnName": "sourceSensor", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_glucoseValues_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_glucoseValues_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_glucoseValues_sourceSensor", + "unique": false, + "columnNames": [ + "sourceSensor" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_sourceSensor` ON `${TABLE_NAME}` (`sourceSensor`)" + }, + { + "name": "index_glucoseValues_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_glucoseValues_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_glucoseValues_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "glucoseValues", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "profileSwitches", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `basalBlocks` TEXT NOT NULL, `isfBlocks` TEXT NOT NULL, `icBlocks` TEXT NOT NULL, `targetBlocks` TEXT NOT NULL, `glucoseUnit` TEXT NOT NULL, `profileName` TEXT NOT NULL, `timeshift` INTEGER NOT NULL, `percentage` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT NOT NULL, `insulinEndTime` INTEGER NOT NULL, `peak` INTEGER NOT NULL, FOREIGN KEY(`referenceId`) REFERENCES `profileSwitches`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "basalBlocks", + "columnName": "basalBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isfBlocks", + "columnName": "isfBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icBlocks", + "columnName": "icBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "targetBlocks", + "columnName": "targetBlocks", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "glucoseUnit", + "columnName": "glucoseUnit", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "profileName", + "columnName": "profileName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timeshift", + "columnName": "timeshift", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "percentage", + "columnName": "percentage", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "insulinConfiguration.insulinLabel", + "columnName": "insulinLabel", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "insulinConfiguration.insulinEndTime", + "columnName": "insulinEndTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "insulinConfiguration.peak", + "columnName": "peak", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_profileSwitches_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_profileSwitches_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + }, + { + "name": "index_profileSwitches_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_profileSwitches_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_profileSwitches_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_profileSwitches_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + } + ], + "foreignKeys": [ + { + "table": "profileSwitches", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "temporaryBasals", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `type` TEXT NOT NULL, `isAbsolute` INTEGER NOT NULL, `rate` REAL NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isAbsolute", + "columnName": "isAbsolute", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "rate", + "columnName": "rate", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_temporaryBasals_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_temporaryBasals_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_temporaryBasals_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_temporaryBasals_pumpType", + "unique": false, + "columnNames": [ + "pumpType" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_pumpType` ON `${TABLE_NAME}` (`pumpType`)" + }, + { + "name": "index_temporaryBasals_endId", + "unique": false, + "columnNames": [ + "endId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_endId` ON `${TABLE_NAME}` (`endId`)" + }, + { + "name": "index_temporaryBasals_pumpSerial", + "unique": false, + "columnNames": [ + "pumpSerial" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" + }, + { + "name": "index_temporaryBasals_temporaryId", + "unique": false, + "columnNames": [ + "temporaryId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_temporaryId` ON `${TABLE_NAME}` (`temporaryId`)" + }, + { + "name": "index_temporaryBasals_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_temporaryBasals_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryBasals_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "temporaryBasals", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "temporaryTargets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `reason` TEXT NOT NULL, `highTarget` REAL NOT NULL, `lowTarget` REAL NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `temporaryTargets`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "reason", + "columnName": "reason", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "highTarget", + "columnName": "highTarget", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "lowTarget", + "columnName": "lowTarget", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_temporaryTargets_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_temporaryTargets_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_temporaryTargets_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_temporaryTargets_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_temporaryTargets_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_temporaryTargets_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "temporaryTargets", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "therapyEvents", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `type` TEXT NOT NULL, `note` TEXT, `enteredBy` TEXT, `glucose` REAL, `glucoseType` TEXT, `glucoseUnit` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `therapyEvents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "note", + "columnName": "note", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enteredBy", + "columnName": "enteredBy", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "glucose", + "columnName": "glucose", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "glucoseType", + "columnName": "glucoseType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "glucoseUnit", + "columnName": "glucoseUnit", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_therapyEvents_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_therapyEvents_type", + "unique": false, + "columnNames": [ + "type" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_type` ON `${TABLE_NAME}` (`type`)" + }, + { + "name": "index_therapyEvents_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_therapyEvents_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_therapyEvents_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_therapyEvents_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_therapyEvents_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "therapyEvents", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "totalDailyDoses", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `basalAmount` REAL NOT NULL, `bolusAmount` REAL NOT NULL, `totalAmount` REAL NOT NULL, `carbs` REAL NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `totalDailyDoses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "basalAmount", + "columnName": "basalAmount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "bolusAmount", + "columnName": "bolusAmount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "totalAmount", + "columnName": "totalAmount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "carbs", + "columnName": "carbs", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_totalDailyDoses_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_totalDailyDoses_pumpId", + "unique": false, + "columnNames": [ + "pumpId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_pumpId` ON `${TABLE_NAME}` (`pumpId`)" + }, + { + "name": "index_totalDailyDoses_pumpType", + "unique": false, + "columnNames": [ + "pumpType" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_pumpType` ON `${TABLE_NAME}` (`pumpType`)" + }, + { + "name": "index_totalDailyDoses_pumpSerial", + "unique": false, + "columnNames": [ + "pumpSerial" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_pumpSerial` ON `${TABLE_NAME}` (`pumpSerial`)" + }, + { + "name": "index_totalDailyDoses_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_totalDailyDoses_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_totalDailyDoses_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_totalDailyDoses_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "totalDailyDoses", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "apsResultLinks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `apsResultId` INTEGER NOT NULL, `smbId` INTEGER, `tbrId` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`apsResultId`) REFERENCES `apsResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`smbId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`tbrId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `apsResultLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "apsResultId", + "columnName": "apsResultId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "smbId", + "columnName": "smbId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tbrId", + "columnName": "tbrId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_apsResultLinks_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_apsResultLinks_apsResultId", + "unique": false, + "columnNames": [ + "apsResultId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_apsResultId` ON `${TABLE_NAME}` (`apsResultId`)" + }, + { + "name": "index_apsResultLinks_smbId", + "unique": false, + "columnNames": [ + "smbId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_smbId` ON `${TABLE_NAME}` (`smbId`)" + }, + { + "name": "index_apsResultLinks_tbrId", + "unique": false, + "columnNames": [ + "tbrId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_apsResultLinks_tbrId` ON `${TABLE_NAME}` (`tbrId`)" + } + ], + "foreignKeys": [ + { + "table": "apsResults", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "apsResultId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "boluses", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "smbId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "temporaryBasals", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "tbrId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "apsResultLinks", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "multiwaveBolusLinks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `bolusId` INTEGER NOT NULL, `extendedBolusId` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`bolusId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`extendedBolusId`) REFERENCES `extendedBoluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `multiwaveBolusLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "bolusId", + "columnName": "bolusId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "extendedBolusId", + "columnName": "extendedBolusId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_multiwaveBolusLinks_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_multiwaveBolusLinks_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_multiwaveBolusLinks_bolusId", + "unique": false, + "columnNames": [ + "bolusId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_multiwaveBolusLinks_bolusId` ON `${TABLE_NAME}` (`bolusId`)" + }, + { + "name": "index_multiwaveBolusLinks_extendedBolusId", + "unique": false, + "columnNames": [ + "extendedBolusId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_multiwaveBolusLinks_extendedBolusId` ON `${TABLE_NAME}` (`extendedBolusId`)" + } + ], + "foreignKeys": [ + { + "table": "boluses", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "bolusId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "extendedBoluses", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "extendedBolusId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "multiwaveBolusLinks", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "preferenceChanges", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `key` TEXT NOT NULL, `value` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "versionChanges", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `versionCode` INTEGER NOT NULL, `versionName` TEXT NOT NULL, `gitRemote` TEXT, `commitHash` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "versionCode", + "columnName": "versionCode", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "versionName", + "columnName": "versionName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "gitRemote", + "columnName": "gitRemote", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "commitHash", + "columnName": "commitHash", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "userEntry", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `action` TEXT NOT NULL, `source` TEXT NOT NULL, `note` TEXT NOT NULL, `values` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "action", + "columnName": "action", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "note", + "columnName": "note", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "values", + "columnName": "values", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_userEntry_source", + "unique": false, + "columnNames": [ + "source" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_userEntry_source` ON `${TABLE_NAME}` (`source`)" + }, + { + "name": "index_userEntry_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_userEntry_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "foods", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `name` TEXT NOT NULL, `category` TEXT, `subCategory` TEXT, `portion` REAL NOT NULL, `carbs` INTEGER NOT NULL, `fat` INTEGER, `protein` INTEGER, `energy` INTEGER, `unit` TEXT NOT NULL, `gi` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `foods`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "category", + "columnName": "category", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subCategory", + "columnName": "subCategory", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "portion", + "columnName": "portion", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "carbs", + "columnName": "carbs", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fat", + "columnName": "fat", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "protein", + "columnName": "protein", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "energy", + "columnName": "energy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "unit", + "columnName": "unit", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "gi", + "columnName": "gi", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_foods_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_foods_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_foods_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_foods_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_foods_isValid` ON `${TABLE_NAME}` (`isValid`)" + } + ], + "foreignKeys": [ + { + "table": "foods", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "deviceStatus", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `device` TEXT, `pump` TEXT, `enacted` TEXT, `suggested` TEXT, `iob` TEXT, `uploaderBattery` INTEGER NOT NULL, `configuration` TEXT, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "device", + "columnName": "device", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pump", + "columnName": "pump", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enacted", + "columnName": "enacted", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "suggested", + "columnName": "suggested", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "iob", + "columnName": "iob", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "uploaderBattery", + "columnName": "uploaderBattery", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "configuration", + "columnName": "configuration", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_deviceStatus_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_deviceStatus_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_deviceStatus_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_deviceStatus_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_deviceStatus_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_deviceStatus_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "offlineEvents", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `reason` TEXT NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `offlineEvents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isValid", + "columnName": "isValid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "reason", + "columnName": "reason", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "duration", + "columnName": "duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutSystemId", + "columnName": "nightscoutSystemId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.nightscoutId", + "columnName": "nightscoutId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpType", + "columnName": "pumpType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpSerial", + "columnName": "pumpSerial", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.temporaryId", + "columnName": "temporaryId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.pumpId", + "columnName": "pumpId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.startId", + "columnName": "startId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "interfaceIDs_backing.endId", + "columnName": "endId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_offlineEvents_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_id` ON `${TABLE_NAME}` (`id`)" + }, + { + "name": "index_offlineEvents_isValid", + "unique": false, + "columnNames": [ + "isValid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_isValid` ON `${TABLE_NAME}` (`isValid`)" + }, + { + "name": "index_offlineEvents_nightscoutId", + "unique": false, + "columnNames": [ + "nightscoutId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_nightscoutId` ON `${TABLE_NAME}` (`nightscoutId`)" + }, + { + "name": "index_offlineEvents_referenceId", + "unique": false, + "columnNames": [ + "referenceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_referenceId` ON `${TABLE_NAME}` (`referenceId`)" + }, + { + "name": "index_offlineEvents_timestamp", + "unique": false, + "columnNames": [ + "timestamp" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_offlineEvents_timestamp` ON `${TABLE_NAME}` (`timestamp`)" + } + ], + "foreignKeys": [ + { + "table": "offlineEvents", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "referenceId" + ], + "referencedColumns": [ + "id" + ] + } + ] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'dda7fa990182c143f1b89139d96e40f7')" + ] + } +} \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/AppDatabase.kt b/database/src/main/java/info/nightscout/androidaps/database/AppDatabase.kt index 58fc350cec5..9273879fe2a 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/AppDatabase.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/AppDatabase.kt @@ -6,7 +6,7 @@ import androidx.room.TypeConverters import info.nightscout.androidaps.database.daos.* import info.nightscout.androidaps.database.entities.* -const val DATABASE_VERSION = 22 +const val DATABASE_VERSION = 23 @Database(version = DATABASE_VERSION, entities = [APSResult::class, Bolus::class, BolusCalculatorResult::class, Carbs::class, diff --git a/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt b/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt index a7093c55bbf..cdb77dc1258 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt @@ -1,6 +1,8 @@ package info.nightscout.androidaps.database import android.content.Context +import android.database.Cursor +import android.database.sqlite.SQLiteException import androidx.room.Room import androidx.room.RoomDatabase.Callback import androidx.room.migration.Migration @@ -26,8 +28,11 @@ open class DatabaseModule { // .addMigrations(migration6to7) // .addMigrations(migration7to8) // .addMigrations(migration11to12) - .addMigrations(migration20to21) - .addMigrations(migration21to22) + .addMigrations( + migration20to21, + migration21to22, + migration22to23, + ) .addCallback(object : Callback() { override fun onOpen(db: SupportSQLiteDatabase) { super.onOpen(db) @@ -73,11 +78,35 @@ open class DatabaseModule { private val migration21to22 = object : Migration(21,22) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("ALTER TABLE `carbs` ADD COLUMN `notes` TEXT") - database.execSQL("ALTER TABLE `boluses` ADD COLUMN `notes` TEXT") + addColumnIfNotExists(database,"carbs", "notes", "TEXT") + addColumnIfNotExists(database,"boluses", "notes", "TEXT") // Custom indexes must be dropped on migration to pass room schema checking after upgrade dropCustomIndexes(database) } } + private val migration22to23 = object : Migration(22,23) { + override fun migrate(database: SupportSQLiteDatabase) { + addColumnIfNotExists(database,"glucoseValues", "smoothed", "REAL") + dropCustomIndexes(database) + } + } + + private fun addColumnIfNotExists(db: SupportSQLiteDatabase, table: String, columnToCheck: String, columnTypeDefinition: String) { + if(!columnExistsInTable(db, table, columnToCheck)) { + db.execSQL("ALTER TABLE `$table` ADD COLUMN `$columnToCheck` $columnTypeDefinition") + } + } + + private fun columnExistsInTable(db: SupportSQLiteDatabase?, table: String, columnToCheck: String?): Boolean { + var cursor: Cursor? = null + return try { + cursor = db?.query("SELECT * FROM $table LIMIT 0", null) + cursor?.getColumnIndex(columnToCheck) !== -1 + } catch (Exp: SQLiteException) { + false + } finally { + cursor?.close() + } + } } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt index 7a0e008e498..487f67318bc 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/GlucoseValue.kt @@ -39,6 +39,7 @@ data class GlucoseValue( override var utcOffset: Long = TimeZone.getDefault().getOffset(timestamp).toLong(), var raw: Double?, var value: Double, + var smoothed: Double?, var trendArrow: TrendArrow, var noise: Double?, var sourceSensor: SourceSensor diff --git a/database/src/main/java/info/nightscout/androidaps/database/transactions/CgmSourceTransaction.kt b/database/src/main/java/info/nightscout/androidaps/database/transactions/CgmSourceTransaction.kt index 382aed5cdeb..1feed391aff 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/transactions/CgmSourceTransaction.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/transactions/CgmSourceTransaction.kt @@ -1,8 +1,10 @@ package info.nightscout.androidaps.database.transactions import info.nightscout.androidaps.database.entities.GlucoseValue -import info.nightscout.androidaps.database.entities.ProfileSwitch import info.nightscout.androidaps.database.entities.TherapyEvent +import java.util.ArrayList +import kotlin.math.max +import kotlin.math.round /** * Inserts data from a CGM source into the database @@ -11,7 +13,9 @@ class CgmSourceTransaction( private val glucoseValues: List, private val calibrations: List, private val sensorInsertionTime: Long?, - private val syncer: Boolean = false // caller is not native source ie. NS + private val syncer: Boolean = false, // caller is not native source ie. NS + private var bgReadings: List = listOf(), + private val updateWindow: Int = 10 // max number of smoothed glucose values to be updated per cycle to avoid updating the database with all entries stored in bgReadings // syncer is allowed create records // update synchronization ID ) : Transaction() { @@ -24,6 +28,7 @@ class CgmSourceTransaction( timestamp = it.timestamp, raw = it.raw, value = it.value, + smoothed = it.smoothed, noise = it.noise, trendArrow = it.trendArrow, sourceSensor = it.sourceSensor @@ -35,6 +40,13 @@ class CgmSourceTransaction( current?.let { existing -> glucoseValue.interfaceIDs.nightscoutId = existing.interfaceIDs.nightscoutId } // preserve invalidated status (user may delete record in UI) current?.let { existing -> glucoseValue.isValid = existing.isValid } + // calculate smoothed values and update DB entries + bgReadings += database.glucoseValueDao.compatGetBgReadingsDataFromTime(glucoseValue.timestamp - 125 * 60 * 1000, glucoseValue.timestamp) //MP Get all readings from up to 125 mins ago + .blockingGet() + bgReadings += glucoseValue + bgReadings = smooth(bgReadings.reversed(), updateWindow) //reverse the list as the smoothing function expects the 0th entry to be the most recent one + //bgReadings += database.glucoseValueDao.findByTimestampAndSensor(it.timestamp, it.sourceSensor) + glucoseValue.smoothed = bgReadings[0].smoothed when { // new record, create new current == null -> { @@ -55,6 +67,12 @@ class CgmSourceTransaction( } } } + // Update the smoothed glucose values of the entries included in bgReadings + bgReadings = bgReadings.reversed().takeLast(updateWindow) // reverse again so that in the DB, the newest values have the largest ID (for cosmetic and logical reasons :P). Also, keep only the last 10 entries to avoid unnecessarily updating older values that + for (i in bgReadings) { + database.glucoseValueDao.updateExistingEntry(i) + result.updated.add(i) + } calibrations.forEach { if (database.therapyEventDao.findByTimestamp(TherapyEvent.Type.FINGER_STICK_BG_VALUE, it.timestamp) == null) { val therapyEvent = TherapyEvent( @@ -81,10 +99,119 @@ class CgmSourceTransaction( return result } + private fun smooth(Data: List, updateWindow: Int): List { + /** + * TSUNAMI DATA SMOOTHING CORE + * + * Calculated a weighted average of 1st and 2nd order exponential smoothing functions + * to reduce the effect of sensor noise on APS performance. The weighted average + * is a compromise between the fast response to changing BGs at the cost of smoothness + * as offered by 1st order exponential smoothing, and the predictive, trend-sensitive but + * slower-to-respond smoothing as offered by 2nd order functions. + * + */ + val sizeRecords = Data.size + val o1_sBG: ArrayList = ArrayList() //MP array for 1st order Smoothed Blood Glucose + val o2_sBG: ArrayList = ArrayList() //MP array for 2nd order Smoothed Blood Glucose + val o2_sD: ArrayList = ArrayList() //MP array for 2nd order Smoothed delta + val ssBG: ArrayList = ArrayList() //MP array for weighted averaged, doubly smoothed Blood Glucose + //val ssD: ArrayList = ArrayList() //MP array for deltas of doubly smoothed Blood Glucose + var windowSize = 25 //MP number of bg readings to include in smoothing window + val o1_weight = 0.4 + val o1_a = 0.5 + val o2_a = 0.4 + val o2_b = 1.0 + var insufficientSmoothingData = false + + // ADJUST SMOOTHING WINDOW TO ONLY INCLUDE VALID READINGS + // Valid readings include: + // - Values that actually exist (windowSize may not be larger than sizeRecords) + // - Values that come in approx. every 5 min. If the time gap between two readings is larger, this is likely due to a sensor error or warmup of a new sensor.d + // - Values that are not 38 mg/dl; 38 mg/dl reflects an xDrip error state (according to a comment in determine-basal.js) + + //MP: Adjust smoothing window if database size is smaller than the default value + 1 (+1 because the reading before the oldest reading to be smoothed will be used in the calculations + if (sizeRecords <= windowSize) { //MP standard smoothing window + windowSize = + (sizeRecords - 1).coerceAtLeast(0) //MP Adjust smoothing window to the size of database if it is smaller than the original window size; -1 to always have at least one older value to compare against as a buffer to prevent app crashes + } + + //MP: Adjust smoothing window further if a gap in the BG database is detected, e.g. due to sensor errors of sensor swaps, or if 38 mg/dl are reported (xDrip error state) + for (i in 0 until windowSize) { + if (Math.round((Data[i].timestamp - Data[i + 1].timestamp) / (1000.0 * 60)) >= 12) { //MP: 12 min because a missed reading (i.e. readings coming in after 10 min) can occur for various reasons, like walking away from the phone or reinstalling AAPS + //if (Math.round((data.get(i).date - data.get(i + 1).date) / 60000L) <= 7) { //MP crashes the app, useful for testing + windowSize = + i + 1 //MP: If time difference between two readings exceeds 7 min, adjust windowSize to *include* the more recent reading (i = reading; +1 because windowSize reflects number of valid readings); + break + } else if (Data[i].value == 38.0) { + windowSize = i //MP: 38 mg/dl reflects an xDrip error state; Chain of valid readings ends here, *exclude* this value (windowSize = i; i + 1 would include the current value) + break + } + } + + // CALCULATE SMOOTHING WINDOW - 1st order exponential smoothing + o1_sBG.clear() // MP reset smoothed bg array + + if (windowSize >= 4) { //MP: Require a valid windowSize of at least 4 readings + o1_sBG.add(Data[windowSize - 1].value) //MP: Initialise smoothing with the oldest valid data point + for (i in 0 until windowSize) { //MP calculate smoothed bg window of valid readings + o1_sBG.add( + 0, + o1_sBG[0] + o1_a * (Data[windowSize - 1 - i].value - o1_sBG[0]) + ) //MP build array of 1st order smoothed bgs + } + } else { + insufficientSmoothingData = true + } + + // CALCULATE SMOOTHING WINDOW - 2nd order exponential smoothing + if (windowSize >= 4) { //MP: Require a valid windowSize of at least 4 readings + o2_sBG.add(Data[windowSize - 1].value) //MP Start 2nd order exponential data smoothing with the oldest valid bg + o2_sD.add(Data[windowSize - 2].value - Data[windowSize - 1].value) //MP Start 2nd order exponential data smoothing with the oldest valid delta + for (i in 0 until windowSize - 1) { //MP calculated smoothed bg window of last 1 h + o2_sBG.add( + 0, + o2_a * Data[windowSize - 2 - i].value + (1 - o2_a) * (o2_sBG[0] + o2_sD[0]) + ) //MP build array of 2nd order smoothed bgs; windowSize-1 is the oldest valid bg value, so windowSize-2 is from when on the smoothing begins; + o2_sD.add( + 0, + o2_b * (o2_sBG[0] - o2_sBG[1]) + (1 - o2_b) * o2_sD[0] + ) //MP build array of 1st order smoothed bgs + } + } else { + insufficientSmoothingData = true + } + + // CALCULATE WEIGHTED AVERAGES OF GLUCOSE & DELTAS + //ssBG.clear() // MP reset doubly smoothed bg array + //ssD.clear() // MP reset doubly smoothed delta array + + if (!insufficientSmoothingData) { //MP Build doubly smoothed array only if there is enough valid readings + for (i in o2_sBG.indices) { //MP calculated doubly smoothed bg of all o1/o2 smoothed data available; o2 & o1 smoothbg array sizes are equal in size, so only one is used as a condition here + ssBG.add(o1_weight * o1_sBG[i] + (1 - o1_weight) * o2_sBG[i]) //MP build array of doubly smoothed bgs + } + /* + for (i in 0 until ssBG.size - 1) { + ssD.add(ssBG[i] - ssBG[i + 1]) //MP build array of doubly smoothed bg deltas + } + */ + for (i in 0 until minOf(ssBG.size, updateWindow)) { // noise at the beginning of the smoothing window is the greatest, so only include the 10 most recent values in the output + Data[i].smoothed = max(round(ssBG[i]), 39.0) //Make 39 the smallest value as smaller values trigger errors (xDrip error state = 38) + } + } else { + for (i in 0 until minOf(Data.size, updateWindow)) { // noise at the beginning of the smoothing window is the greatest, so only include the 10 most recent values in the output + Data[i].smoothed = max(Data[i].value, 39.0) // if insufficient smoothing data, copy 'value' into 'smoothed' data column so that it isn't empty; Make 39 the smallest value as smaller + // values trigger errors (xDrip error state = 38) + } + } + + return Data + } + data class TransactionGlucoseValue( val timestamp: Long, val value: Double, val raw: Double?, + val smoothed: Double?, val noise: Double?, val trendArrow: GlucoseValue.TrendArrow, val nightscoutId: String? = null, diff --git a/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index dc7e6d803b1..b25d871e325 100644 --- a/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -324,11 +324,11 @@ class SmsCommunicatorPlugin @Inject constructor( var reply = "" val units = profileFunction.getUnits() if (actualBG != null) { - reply = rh.gs(R.string.sms_actual_bg) + " " + actualBG.valueToUnitsString(units) + ", " + reply = rh.gs(R.string.sms_actual_bg) + " " + actualBG.valueToUnitsString(units, sp) + ", " } else if (lastBG != null) { val agoMilliseconds = dateUtil.now() - lastBG.timestamp val agoMin = (agoMilliseconds / 60.0 / 1000.0).toInt() - reply = rh.gs(R.string.sms_last_bg) + " " + lastBG.valueToUnitsString(units) + " " + rh.gs(R.string.sms_min_ago, agoMin) + ", " + reply = rh.gs(R.string.sms_last_bg) + " " + lastBG.valueToUnitsString(units, sp) + " " + rh.gs(R.string.sms_min_ago, agoMin) + ", " } val glucoseStatus = glucoseStatusProvider.glucoseStatusData if (glucoseStatus != null) reply += rh.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", " diff --git a/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt index b9083fcf9b6..b517e9a1e68 100644 --- a/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt @@ -81,7 +81,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { private var hasBeenRun = false @Before fun prepareTests() { - val reading = GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT) + val reading = GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, smoothed = null, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT) val bgList: MutableList = ArrayList() bgList.add(reading) diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt index 2dbe5511ade..1366ef4b438 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt @@ -17,6 +17,7 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.extensions.formatColor +import info.nightscout.androidaps.extensions.rawOrSmoothed import info.nightscout.androidaps.interfaces.ActivityNames import info.nightscout.androidaps.interfaces.BolusTimer import info.nightscout.androidaps.interfaces.CarbTimer @@ -197,7 +198,7 @@ class CarbsDialog : DialogFragmentWithDate() { } iobCobCalculator.ads.actualBg()?.let { bgReading -> - if (bgReading.value < 72) + if (bgReading.rawOrSmoothed(sp) < 72) binding.hypoTt.isChecked = true } binding.hypoTt.setOnClickListener { diff --git a/ui/src/main/java/info/nightscout/ui/widget/Widget.kt b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt index 2cdef86ef5b..b6383b35b17 100644 --- a/ui/src/main/java/info/nightscout/ui/widget/Widget.kt +++ b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt @@ -124,7 +124,7 @@ class Widget : AppWidgetProvider() { private fun updateBg(views: RemoteViews) { val units = profileFunction.getUnits() - views.setTextViewText(R.id.bg, overviewData.lastBg?.valueToUnitsString(units) ?: rh.gs(R.string.value_unavailable_short)) + views.setTextViewText(R.id.bg, overviewData.lastBg?.valueToUnitsString(units, sp) ?: rh.gs(R.string.value_unavailable_short)) views.setTextColor( R.id.bg, when { overviewData.isLow -> rh.gc(R.color.widget_low)