Merge pull request #1851 from Philoul/Autotune/UnitTests
Add Unit test for AutotunePrep
This commit is contained in:
commit
5ea5e80393
|
@ -29,7 +29,7 @@ import kotlin.math.ceil
|
|||
import kotlin.math.roundToInt
|
||||
|
||||
@Singleton
|
||||
class AutotuneIob @Inject constructor(
|
||||
open class AutotuneIob @Inject constructor(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val repository: AppRepository,
|
||||
private val profileFunction: ProfileFunction,
|
||||
|
@ -41,10 +41,10 @@ class AutotuneIob @Inject constructor(
|
|||
|
||||
private val nsTreatments = ArrayList<NsTreatment>()
|
||||
private var dia: Double = Constants.defaultDIA
|
||||
var boluses: MutableList<Bolus> = ArrayList()
|
||||
var boluses: ArrayList<Bolus> = ArrayList()
|
||||
var meals = ArrayList<Carbs>()
|
||||
lateinit var glucose: List<GlucoseValue> // newest at index 0
|
||||
private lateinit var tempBasals: MutableList<TemporaryBasal>
|
||||
private lateinit var tempBasals: ArrayList<TemporaryBasal>
|
||||
var startBG: Long = 0
|
||||
var endBG: Long = 0
|
||||
private fun range(): Long = (60 * 60 * 1000L * dia + T.hours(2).msecs()).toLong()
|
||||
|
@ -225,7 +225,7 @@ class AutotuneIob @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun getIOB(time: Long, localInsulin: LocalInsulin): IobTotal {
|
||||
open fun getIOB(time: Long, localInsulin: LocalInsulin): IobTotal {
|
||||
val bolusIob = getCalculationToTimeTreatments(time, localInsulin).round()
|
||||
return bolusIob
|
||||
}
|
||||
|
|
|
@ -302,7 +302,7 @@ class AutotunePrep @Inject constructor(
|
|||
|
||||
// Then, calculate carb absorption for that 5m interval using the deviation.
|
||||
if (mealCOB > 0) {
|
||||
val ci = Math.max(deviation, sp.getDouble("openapsama_min_5m_carbimpact", 3.0))
|
||||
val ci = Math.max(deviation, sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0))
|
||||
val absorbed = ci * tunedprofile.ic / sens
|
||||
// Store the COB, and use it as the starting point for the next data point.
|
||||
mealCOB = Math.max(0.0, mealCOB - absorbed)
|
||||
|
|
|
@ -30,9 +30,6 @@ class AutotuneCoreTest : TestBaseWithProfile() {
|
|||
@Mock lateinit var injector: HasAndroidInjector
|
||||
@Mock lateinit var activePlugin: ActivePlugin
|
||||
lateinit var autotuneCore: AutotuneCore
|
||||
lateinit var prep: PreppedGlucose
|
||||
lateinit var prepjson: String
|
||||
lateinit var inputProfile: ATProfile
|
||||
var min5mCarbImpact = 0.0
|
||||
var autotuneMin = 0.0
|
||||
var autotuneMax = 0.0
|
||||
|
@ -41,14 +38,15 @@ class AutotuneCoreTest : TestBaseWithProfile() {
|
|||
fun initData() {
|
||||
autotuneCore = AutotuneCore(sp,autotuneFS)
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+2"))
|
||||
prepjson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
val inputProfileJson = File("src/test/res/autotune/test1/profile.pump.json").readText()
|
||||
inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
prep = PreppedGlucose(JSONObject(prepjson), dateUtil)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autotuneCoreTest() { // Test if load from file of OpenAPS categorisation is Ok
|
||||
val prepjson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
val inputProfileJson = File("src/test/res/autotune/test1/profile.pump.json").readText()
|
||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
val prep = PreppedGlucose(JSONObject(prepjson), dateUtil)
|
||||
|
||||
`when`(sp.getDouble(R.string.key_openapsama_autosens_max, 1.2)).thenReturn(autotuneMax)
|
||||
`when`(sp.getDouble(R.string.key_openapsama_autosens_min, 0.7)).thenReturn(autotuneMin)
|
||||
`when`(sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)).thenReturn(min5mCarbImpact)
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
package info.nightscout.androidaps.plugins.general.autotune
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.data.LocalInsulin
|
||||
import info.nightscout.androidaps.data.ProfileSealed
|
||||
import info.nightscout.androidaps.data.PureProfile
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.data.Block
|
||||
import info.nightscout.androidaps.database.data.TargetBlock
|
||||
import info.nightscout.androidaps.database.entities.Bolus
|
||||
import info.nightscout.androidaps.database.entities.Carbs
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.plugins.general.autotune.data.*
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class AutotunePrepTest : TestBaseWithProfile() {
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var autotuneFS: AutotuneFS
|
||||
@Mock lateinit var injector: HasAndroidInjector
|
||||
@Mock lateinit var activePlugin: ActivePlugin
|
||||
@Mock lateinit var repository: AppRepository
|
||||
lateinit var autotunePrep: AutotunePrep
|
||||
lateinit var autotuneIob: TestAutotuneIob
|
||||
lateinit var inputProfile: ATProfile
|
||||
var min5mCarbImpact = 0.0
|
||||
var autotuneMin = 0.0
|
||||
var autotuneMax = 0.0
|
||||
var startDayTime = 0L
|
||||
|
||||
|
||||
@Before
|
||||
fun initData() {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+2"))
|
||||
val inputProfileJson = File("src/test/res/autotune/test1/profile.pump.json").readText()
|
||||
inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
val inputIobJson = File("src/test/res/autotune/test1/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
||||
val iobOapsCalcul = buildIobOaps(JSONArray(inputIobJson))
|
||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalcul)
|
||||
autotunePrep = AutotunePrep(sp, dateUtil, autotuneFS, autotuneIob)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autotunePrepTest() { // Test if load from file of OpenAPS categorisation is Ok
|
||||
val prepjson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
val oapsPreppedGlucose = PreppedGlucose(JSONObject(prepjson), dateUtil) //prep data calculated by OpenAPS autotune
|
||||
val oapsEntriesJson = File("src/test/res/autotune/test1/aaps-entries.2022-05-21.json").readText()
|
||||
autotuneIob.glucose = buildGlucose(JSONArray(oapsEntriesJson))
|
||||
val oapsTreatmentsJson = File("src/test/res/autotune/test1/aaps-treatments.2022-05-21.json").readText()
|
||||
autotuneIob.meals = buildMeals(JSONArray(oapsTreatmentsJson)) //Only meals is used in unit test, Insulin only used for iob calculation
|
||||
autotuneIob.boluses = buildBoluses(oapsPreppedGlucose) //Values from oapsPrepData because linked to iob calculation method for TBR
|
||||
`when`(sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)).thenReturn(min5mCarbImpact)
|
||||
|
||||
val aapsPreppedGlucose = autotunePrep.categorizeBGDatums(inputProfile, inputProfile.localInsulin, false)
|
||||
try {
|
||||
aapsPreppedGlucose?.let { // compare all categorization calculated by aaps plugin (aapsPreppedGlucose) with categorization calculated by OpenAPS (oapsPreppedGlucose)
|
||||
for (i in aapsPreppedGlucose.crData.indices)
|
||||
Assert.assertTrue(oapsPreppedGlucose.crData[i].equals(aapsPreppedGlucose.crData[i]))
|
||||
for (i in aapsPreppedGlucose.csfGlucoseData.indices)
|
||||
Assert.assertTrue(oapsPreppedGlucose.csfGlucoseData[i].equals(aapsPreppedGlucose.csfGlucoseData[i]))
|
||||
for (i in aapsPreppedGlucose.isfGlucoseData.indices)
|
||||
Assert.assertTrue(oapsPreppedGlucose.isfGlucoseData[i].equals(aapsPreppedGlucose.isfGlucoseData[i]))
|
||||
for (i in aapsPreppedGlucose.basalGlucoseData.indices)
|
||||
Assert.assertTrue(oapsPreppedGlucose.basalGlucoseData[i].equals(aapsPreppedGlucose.basalGlucoseData[i]))
|
||||
}
|
||||
?: Assert.fail()
|
||||
} catch (e: Exception) {
|
||||
Assert.fail()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* OpenAPS profile for Autotune only have one ISF value and one IC value
|
||||
*/
|
||||
fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): ATProfile? {
|
||||
try {
|
||||
min5mCarbImpact = JsonHelper.safeGetDoubleAllowNull(jsonObject, "min_5m_carbimpact") ?: return null
|
||||
autotuneMin = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_min") ?: return null
|
||||
autotuneMax = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_max") ?: return null
|
||||
val txtUnits = JsonHelper.safeGetStringAllowNull(jsonObject, "units", defaultUnits) ?: return null
|
||||
val units = GlucoseUnit.fromText(txtUnits)
|
||||
val dia = JsonHelper.safeGetDoubleAllowNull(jsonObject, "dia") ?: return null
|
||||
val peak = JsonHelper.safeGetIntAllowNull(jsonObject, "insulinPeakTime") ?: return null
|
||||
val localInsulin = LocalInsulin("insulin", peak, dia)
|
||||
val timezone = TimeZone.getTimeZone(JsonHelper.safeGetString(jsonObject, "timezone", "UTC"))
|
||||
val isfJson = jsonObject.getJSONObject("isfProfile")
|
||||
val isfBlocks = ArrayList<Block>(1).also {
|
||||
val isfJsonArray = isfJson.getJSONArray("sensitivities")
|
||||
val value = isfJsonArray.getJSONObject(0).getDouble("sensitivity")
|
||||
it.add(0,Block((T.hours(24).secs()) * 1000L, value))
|
||||
}
|
||||
val icBlocks = ArrayList<Block>(1).also {
|
||||
val value = jsonObject.getDouble("carb_ratio")
|
||||
it.add(0,Block((T.hours(24).secs()) * 1000L, value))
|
||||
}
|
||||
val basalBlocks = blockFromJsonArray(jsonObject.getJSONArray("basalprofile"), dateUtil)
|
||||
?: return null
|
||||
val targetBlocks = ArrayList<TargetBlock>(1).also {
|
||||
it.add(0, TargetBlock((T.hours(24).secs()) * 1000L, 100.0, 100.0))
|
||||
}
|
||||
|
||||
val pure = PureProfile(
|
||||
jsonObject = jsonObject,
|
||||
basalBlocks = basalBlocks,
|
||||
isfBlocks = isfBlocks,
|
||||
icBlocks = icBlocks,
|
||||
targetBlocks = targetBlocks,
|
||||
glucoseUnit = units,
|
||||
timeZone = timezone,
|
||||
dia = dia
|
||||
)
|
||||
return ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil}
|
||||
} catch (ignored: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun blockFromJsonArray(jsonArray: JSONArray?, dateUtil: DateUtil): List<Block>? {
|
||||
val size = jsonArray?.length() ?: return null
|
||||
val ret = ArrayList<Block>(size)
|
||||
try {
|
||||
for (index in 0 until jsonArray.length() - 1) {
|
||||
val o = jsonArray.getJSONObject(index)
|
||||
val tas = o.getInt("minutes") * 60
|
||||
val next = jsonArray.getJSONObject(index + 1)
|
||||
val nextTas = next.getInt("minutes") * 60
|
||||
val value = o.getDouble("rate")
|
||||
if (tas % 3600 != 0) return null
|
||||
if (nextTas % 3600 != 0) return null
|
||||
ret.add(index, Block((nextTas - tas) * 1000L, value))
|
||||
}
|
||||
val last: JSONObject = jsonArray.getJSONObject(jsonArray.length() - 1)
|
||||
val lastTas = last.getInt("minutes") * 60
|
||||
val value = last.getDouble("rate")
|
||||
ret.add(jsonArray.length() - 1, Block((T.hours(24).secs() - lastTas) * 1000L, value))
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
fun buildBoluses(preppedGlucose: PreppedGlucose): ArrayList<Bolus> { //if categorization is correct then I return for dose function the crInsulin calculated in Oaps
|
||||
val boluses: ArrayList<Bolus> = ArrayList()
|
||||
try {
|
||||
for (i in preppedGlucose.crData.indices) {
|
||||
boluses.add(
|
||||
Bolus(
|
||||
timestamp = preppedGlucose.crData[i].crEndTime,
|
||||
amount = preppedGlucose.crData[i].crInsulin,
|
||||
type = Bolus.Type.NORMAL
|
||||
)
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) { }
|
||||
return boluses
|
||||
}
|
||||
|
||||
fun buildMeals(jsonArray: JSONArray): ArrayList<Carbs> {
|
||||
val list: ArrayList<Carbs> = ArrayList()
|
||||
try {
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val value = JsonHelper.safeGetDouble(json, "carbs", 0.0)
|
||||
val timestamp = JsonHelper.safeGetLong(json, "date")
|
||||
if (value > 0.0 && timestamp > startDayTime) {
|
||||
list.add(Carbs(timestamp=timestamp, amount = value, duration = 0))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) { }
|
||||
return list
|
||||
}
|
||||
|
||||
fun buildGlucose(jsonArray: JSONArray): List<GlucoseValue> {
|
||||
val list: ArrayList<GlucoseValue> = ArrayList()
|
||||
try {
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val value = JsonHelper.safeGetDouble(json, "sgv")
|
||||
val timestamp = JsonHelper.safeGetLong(json, "date")
|
||||
list.add(GlucoseValue(raw = value, noise = 0.0, value = value, timestamp = timestamp, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
}
|
||||
} catch (e: Exception) { }
|
||||
if (list.size > 0)
|
||||
startDayTime = list[list.size-1].timestamp
|
||||
return list
|
||||
}
|
||||
|
||||
fun buildIobOaps(jsonArray: JSONArray): ArrayList<IobTotal> { //if categorization is correct then I return for dose function the crInsulin calculated in Oaps
|
||||
val list: ArrayList<IobTotal> = ArrayList()
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val time = JsonHelper.safeGetLong(json,"date")
|
||||
val iob = JsonHelper.safeGetDouble(json, "iob")
|
||||
val activity = JsonHelper.safeGetDouble(json, "activity")
|
||||
val iobTotal = IobTotal(time)
|
||||
iobTotal.iob = iob
|
||||
iobTotal.activity = activity
|
||||
list.add(iobTotal)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
class TestAutotuneIob(
|
||||
val aapsLogger: AAPSLogger,
|
||||
repository: AppRepository,
|
||||
val profileFunction: ProfileFunction,
|
||||
val sp: SP,
|
||||
val dateUtil: DateUtil,
|
||||
val activePlugin: ActivePlugin,
|
||||
autotuneFS: AutotuneFS,
|
||||
val iobOapsCalcul: ArrayList<IobTotal>
|
||||
) : AutotuneIob(
|
||||
aapsLogger,
|
||||
repository,
|
||||
profileFunction,
|
||||
sp,
|
||||
dateUtil,
|
||||
activePlugin,
|
||||
autotuneFS
|
||||
) {
|
||||
override fun getIOB(time: Long, localInsulin: LocalInsulin): IobTotal {
|
||||
var bolusIob = IobTotal(time)
|
||||
iobOapsCalcul.forEach {
|
||||
if (it.time == time)
|
||||
return it
|
||||
}
|
||||
return bolusIob
|
||||
}
|
||||
}
|
||||
}
|
BIN
app/src/test/res/autotune/test1/Convert_Log2JSON.xlsx
Normal file
BIN
app/src/test/res/autotune/test1/Convert_Log2JSON.xlsx
Normal file
Binary file not shown.
286
app/src/test/res/autotune/test1/oaps-iobCalc.2022-05-21.json
Normal file
286
app/src/test/res/autotune/test1/oaps-iobCalc.2022-05-21.json
Normal file
|
@ -0,0 +1,286 @@
|
|||
[
|
||||
{ "iob": 5.249, "activity": 0.0391, "date": 1653099848000},
|
||||
{ "iob": 5.292, "activity": 0.0438, "date": 1653100148000},
|
||||
{ "iob": 4.964, "activity": 0.047, "date": 1653100449000},
|
||||
{ "iob": 4.674, "activity": 0.0489, "date": 1653100748000},
|
||||
{ "iob": 4.377, "activity": 0.0498, "date": 1653101048000},
|
||||
{ "iob": 4.077, "activity": 0.0498, "date": 1653101348000},
|
||||
{ "iob": 3.73, "activity": 0.0491, "date": 1653101648000},
|
||||
{ "iob": 3.389, "activity": 0.0476, "date": 1653101948000},
|
||||
{ "iob": 3.055, "activity": 0.0457, "date": 1653102249000},
|
||||
{ "iob": 2.782, "activity": 0.0436, "date": 1653102548000},
|
||||
{ "iob": 2.47, "activity": 0.0411, "date": 1653102848000},
|
||||
{ "iob": 2.22, "activity": 0.0386, "date": 1653103149000},
|
||||
{ "iob": 1.935, "activity": 0.0358, "date": 1653103448000},
|
||||
{ "iob": 1.711, "activity": 0.0332, "date": 1653103748000},
|
||||
{ "iob": 1.452, "activity": 0.0304, "date": 1653104049000},
|
||||
{ "iob": 1.927, "activity": 0.028, "date": 1653104349000},
|
||||
{ "iob": 1.84, "activity": 0.027, "date": 1653104648000},
|
||||
{ "iob": 1.658, "activity": 0.0258, "date": 1653104949000},
|
||||
{ "iob": 1.482, "activity": 0.0245, "date": 1653105248000},
|
||||
{ "iob": 1.264, "activity": 0.0229, "date": 1653105549000},
|
||||
{ "iob": 1.104, "activity": 0.0212, "date": 1653105848000},
|
||||
{ "iob": 0.952, "activity": 0.0194, "date": 1653106149000},
|
||||
{ "iob": 1.619, "activity": 0.0181, "date": 1653106449000},
|
||||
{ "iob": 1.678, "activity": 0.0184, "date": 1653106749000},
|
||||
{ "iob": 1.775, "activity": 0.0187, "date": 1653107048000},
|
||||
{ "iob": 1.581, "activity": 0.019, "date": 1653107348000},
|
||||
{ "iob": 1.437, "activity": 0.0188, "date": 1653107648000},
|
||||
{ "iob": 1.294, "activity": 0.0183, "date": 1653107948000},
|
||||
{ "iob": 1.153, "activity": 0.0176, "date": 1653108249000},
|
||||
{ "iob": 1.017, "activity": 0.0167, "date": 1653108548000},
|
||||
{ "iob": 0.887, "activity": 0.0156, "date": 1653108848000},
|
||||
{ "iob": 1.011, "activity": 0.0147, "date": 1653109148000},
|
||||
{ "iob": 0.889, "activity": 0.0141, "date": 1653109448000},
|
||||
{ "iob": 0.771, "activity": 0.0133, "date": 1653109748000},
|
||||
{ "iob": 0.656, "activity": 0.0124, "date": 1653110049000},
|
||||
{ "iob": 0.547, "activity": 0.0114, "date": 1653110348000},
|
||||
{ "iob": 0.392, "activity": 0.0103, "date": 1653110649000},
|
||||
{ "iob": 0.294, "activity": 0.0091, "date": 1653110949000},
|
||||
{ "iob": 0.2, "activity": 0.008, "date": 1653111249000},
|
||||
{ "iob": 0.065, "activity": 0.0066, "date": 1653111549000},
|
||||
{ "iob": 0.034, "activity": 0.0055, "date": 1653111849000},
|
||||
{ "iob": 0.549, "activity": 0.0048, "date": 1653112148000},
|
||||
{ "iob": 0.674, "activity": 0.0053, "date": 1653112449000},
|
||||
{ "iob": 0.597, "activity": 0.0057, "date": 1653112749000},
|
||||
{ "iob": 0.468, "activity": 0.0058, "date": 1653113049000},
|
||||
{ "iob": 0.389, "activity": 0.0057, "date": 1653113349000},
|
||||
{ "iob": 0.262, "activity": 0.0053, "date": 1653113649000},
|
||||
{ "iob": 0.186, "activity": 0.0048, "date": 1653113949000},
|
||||
{ "iob": 0.064, "activity": 0.0041, "date": 1653114249000},
|
||||
{ "iob": -0.005, "activity": 0.0034, "date": 1653114549000},
|
||||
{ "iob": -0.12, "activity": 0.0026, "date": 1653114849000},
|
||||
{ "iob": -0.181, "activity": 0.0018, "date": 1653115149000},
|
||||
{ "iob": -0.287, "activity": 0.0008, "date": 1653115449000},
|
||||
{ "iob": -0.34, "activity": 0, "date": 1653115749000},
|
||||
{ "iob": -0.436, "activity": -0.001, "date": 1653116049000},
|
||||
{ "iob": -0.48, "activity": -0.0018, "date": 1653116349000},
|
||||
{ "iob": -0.519, "activity": -0.0026, "date": 1653116649000},
|
||||
{ "iob": -0.554, "activity": -0.0034, "date": 1653116949000},
|
||||
{ "iob": -0.585, "activity": -0.0041, "date": 1653117249000},
|
||||
{ "iob": -0.662, "activity": -0.0049, "date": 1653117549000},
|
||||
{ "iob": -0.687, "activity": -0.0055, "date": 1653117848000},
|
||||
{ "iob": -0.708, "activity": -0.0061, "date": 1653118149000},
|
||||
{ "iob": -0.726, "activity": -0.0066, "date": 1653118449000},
|
||||
{ "iob": -0.351, "activity": -0.0071, "date": 1653118748000},
|
||||
{ "iob": -0.218, "activity": -0.0064, "date": 1653119049000},
|
||||
{ "iob": -0.088, "activity": -0.0055, "date": 1653119349000},
|
||||
{ "iob": 13.594, "activity": 0.0023, "date": 1653119649000},
|
||||
{ "iob": 13.552, "activity": 0.0331, "date": 1653119949000},
|
||||
{ "iob": 13.224, "activity": 0.0573, "date": 1653120249000},
|
||||
{ "iob": 12.838, "activity": 0.076, "date": 1653120548000},
|
||||
{ "iob": 12.322, "activity": 0.09, "date": 1653120849000},
|
||||
{ "iob": 11.794, "activity": 0.1001, "date": 1653121149000},
|
||||
{ "iob": 11.177, "activity": 0.1068, "date": 1653121449000},
|
||||
{ "iob": 10.58, "activity": 0.111, "date": 1653121749000},
|
||||
{ "iob": 9.919, "activity": 0.1129, "date": 1653122049000},
|
||||
{ "iob": 9.254, "activity": 0.1129, "date": 1653122349000},
|
||||
{ "iob": 8.643, "activity": 0.1114, "date": 1653122649000},
|
||||
{ "iob": 7.992, "activity": 0.1088, "date": 1653122949000},
|
||||
{ "iob": 7.406, "activity": 0.1053, "date": 1653123248000},
|
||||
{ "iob": 7.111, "activity": 0.1012, "date": 1653123549000},
|
||||
{ "iob": 6.515, "activity": 0.0971, "date": 1653123849000},
|
||||
{ "iob": 5.99, "activity": 0.0927, "date": 1653124149000},
|
||||
{ "iob": 5.439, "activity": 0.0878, "date": 1653124448000},
|
||||
{ "iob": 4.962, "activity": 0.0828, "date": 1653124749000},
|
||||
{ "iob": 4.462, "activity": 0.0775, "date": 1653125048000},
|
||||
{ "iob": 4.036, "activity": 0.0724, "date": 1653125349000},
|
||||
{ "iob": 3.638, "activity": 0.0672, "date": 1653125649000},
|
||||
{ "iob": 3.214, "activity": 0.0621, "date": 1653125948000},
|
||||
{ "iob": 2.866, "activity": 0.0571, "date": 1653126249000},
|
||||
{ "iob": 2.494, "activity": 0.0522, "date": 1653126549000},
|
||||
{ "iob": 2.193, "activity": 0.0476, "date": 1653126849000},
|
||||
{ "iob": 1.867, "activity": 0.0431, "date": 1653127149000},
|
||||
{ "iob": 1.563, "activity": 0.0388, "date": 1653127449000},
|
||||
{ "iob": 1.329, "activity": 0.0347, "date": 1653127748000},
|
||||
{ "iob": 1.115, "activity": 0.0309, "date": 1653128049000},
|
||||
{ "iob": 0.87, "activity": 0.0272, "date": 1653128349000},
|
||||
{ "iob": 0.692, "activity": 0.0239, "date": 1653128649000},
|
||||
{ "iob": 0.482, "activity": 0.0206, "date": 1653128948000},
|
||||
{ "iob": 0.287, "activity": 0.0176, "date": 1653129249000},
|
||||
{ "iob": 0.156, "activity": 0.0148, "date": 1653129548000},
|
||||
{ "iob": 0.038, "activity": 0.0122, "date": 1653129848000},
|
||||
{ "iob": -0.067, "activity": 0.0099, "date": 1653130149000},
|
||||
{ "iob": -0.161, "activity": 0.0078, "date": 1653130448000},
|
||||
{ "iob": -0.195, "activity": 0.006, "date": 1653130748000},
|
||||
{ "iob": -0.271, "activity": 0.0044, "date": 1653131049000},
|
||||
{ "iob": -0.339, "activity": 0.0029, "date": 1653131349000},
|
||||
{ "iob": -0.4, "activity": 0.0015, "date": 1653131649000},
|
||||
{ "iob": -0.155, "activity": 0.0007, "date": 1653131948000},
|
||||
{ "iob": 8.11, "activity": 0.0045, "date": 1653132249000},
|
||||
{ "iob": 7.992, "activity": 0.0222, "date": 1653132549000},
|
||||
{ "iob": 7.745, "activity": 0.0359, "date": 1653132849000},
|
||||
{ "iob": 7.488, "activity": 0.0465, "date": 1653133149000},
|
||||
{ "iob": 7.136, "activity": 0.0541, "date": 1653133449000},
|
||||
{ "iob": 6.8, "activity": 0.0596, "date": 1653133749000},
|
||||
{ "iob": 6.441, "activity": 0.0633, "date": 1653134049000},
|
||||
{ "iob": 6.022, "activity": 0.0651, "date": 1653134349000},
|
||||
{ "iob": 5.644, "activity": 0.0657, "date": 1653134649000},
|
||||
{ "iob": 5.216, "activity": 0.0653, "date": 1653134949000},
|
||||
{ "iob": 4.962, "activity": 0.0644, "date": 1653135249000},
|
||||
{ "iob": 4.544, "activity": 0.0627, "date": 1653135549000},
|
||||
{ "iob": 4.185, "activity": 0.0606, "date": 1653135849000},
|
||||
{ "iob": 3.839, "activity": 0.058, "date": 1653136149000},
|
||||
{ "iob": 3.456, "activity": 0.055, "date": 1653136449000},
|
||||
{ "iob": 3.139, "activity": 0.0519, "date": 1653136749000},
|
||||
{ "iob": 2.788, "activity": 0.0486, "date": 1653137049000},
|
||||
{ "iob": 2.503, "activity": 0.0453, "date": 1653137350000},
|
||||
{ "iob": 2.186, "activity": 0.0418, "date": 1653137649000},
|
||||
{ "iob": 3.17, "activity": 0.0407, "date": 1653137949000},
|
||||
{ "iob": 3.956, "activity": 0.0413, "date": 1653138249000},
|
||||
{ "iob": 3.648, "activity": 0.042, "date": 1653138549000},
|
||||
{ "iob": 4.126, "activity": 0.043, "date": 1653138849000},
|
||||
{ "iob": 3.81, "activity": 0.0437, "date": 1653139150000},
|
||||
{ "iob": 3.541, "activity": 0.0437, "date": 1653139450000},
|
||||
{ "iob": 3.272, "activity": 0.0431, "date": 1653139749000},
|
||||
{ "iob": 3.588, "activity": 0.0428, "date": 1653140049000},
|
||||
{ "iob": 3.875, "activity": 0.0431, "date": 1653140349000},
|
||||
{ "iob": 3.608, "activity": 0.0434, "date": 1653140648000},
|
||||
{ "iob": 4.271, "activity": 0.0442, "date": 1653140949000},
|
||||
{ "iob": 3.996, "activity": 0.0452, "date": 1653141249000},
|
||||
{ "iob": 4.298, "activity": 0.0462, "date": 1653141548000},
|
||||
{ "iob": 4.015, "activity": 0.0468, "date": 1653141849000},
|
||||
{ "iob": 4.538, "activity": 0.0481, "date": 1653142149000},
|
||||
{ "iob": 4.245, "activity": 0.0489, "date": 1653142449000},
|
||||
{ "iob": 4.729, "activity": 0.05, "date": 1653142749000},
|
||||
{ "iob": 4.426, "activity": 0.0508, "date": 1653143049000},
|
||||
{ "iob": 4.353, "activity": 0.051, "date": 1653143349000},
|
||||
{ "iob": 4.049, "activity": 0.0507, "date": 1653143650000},
|
||||
{ "iob": 3.747, "activity": 0.0498, "date": 1653143949000},
|
||||
{ "iob": 3.402, "activity": 0.0483, "date": 1653144249000},
|
||||
{ "iob": 3.115, "activity": 0.0464, "date": 1653144550000},
|
||||
{ "iob": 2.788, "activity": 0.0441, "date": 1653144849000},
|
||||
{ "iob": 2.524, "activity": 0.0417, "date": 1653145149000},
|
||||
{ "iob": 2.271, "activity": 0.0391, "date": 1653145449000},
|
||||
{ "iob": 2.033, "activity": 0.0365, "date": 1653145750000},
|
||||
{ "iob": 1.807, "activity": 0.0338, "date": 1653146050000},
|
||||
{ "iob": 1.594, "activity": 0.0312, "date": 1653146349000},
|
||||
{ "iob": 1.395, "activity": 0.0286, "date": 1653146650000},
|
||||
{ "iob": 1.258, "activity": 0.0262, "date": 1653146949000},
|
||||
{ "iob": 1.034, "activity": 0.0236, "date": 1653147249000},
|
||||
{ "iob": 0.971, "activity": 0.0215, "date": 1653147549000},
|
||||
{ "iob": 1.008, "activity": 0.0197, "date": 1653147849000},
|
||||
{ "iob": 0.963, "activity": 0.0183, "date": 1653148149000},
|
||||
{ "iob": 1.046, "activity": 0.0171, "date": 1653148450000},
|
||||
{ "iob": 0.912, "activity": 0.0161, "date": 1653148749000},
|
||||
{ "iob": 1.254, "activity": 0.0156, "date": 1653149049000},
|
||||
{ "iob": 1.176, "activity": 0.0154, "date": 1653149349000},
|
||||
{ "iob": 1.051, "activity": 0.0149, "date": 1653149650000},
|
||||
{ "iob": 0.928, "activity": 0.0142, "date": 1653149949000},
|
||||
{ "iob": 1.008, "activity": 0.0138, "date": 1653150249000},
|
||||
{ "iob": 0.89, "activity": 0.0133, "date": 1653150549000},
|
||||
{ "iob": 0.775, "activity": 0.0127, "date": 1653150849000},
|
||||
{ "iob": 0.664, "activity": 0.0118, "date": 1653151149000},
|
||||
{ "iob": 0.606, "activity": 0.011, "date": 1653151449000},
|
||||
{ "iob": 0.703, "activity": 0.0105, "date": 1653151749000},
|
||||
{ "iob": 0.702, "activity": 0.0101, "date": 1653152049000},
|
||||
{ "iob": 0.902, "activity": 0.0101, "date": 1653152349000},
|
||||
{ "iob": 0.801, "activity": 0.0101, "date": 1653152649000},
|
||||
{ "iob": 0.701, "activity": 0.0098, "date": 1653152949000},
|
||||
{ "iob": 0.603, "activity": 0.0094, "date": 1653153249000},
|
||||
{ "iob": 0.508, "activity": 0.0088, "date": 1653153549000},
|
||||
{ "iob": 0.415, "activity": 0.0081, "date": 1653153849000},
|
||||
{ "iob": 0.327, "activity": 0.0074, "date": 1653154149000},
|
||||
{ "iob": 0.242, "activity": 0.0066, "date": 1653154449000},
|
||||
{ "iob": 0.161, "activity": 0.0058, "date": 1653154749000},
|
||||
{ "iob": 0.134, "activity": 0.005, "date": 1653155049000},
|
||||
{ "iob": 0.4, "activity": 0.0048, "date": 1653155349000},
|
||||
{ "iob": 0.475, "activity": 0.0049, "date": 1653155649000},
|
||||
{ "iob": 0.401, "activity": 0.005, "date": 1653155950000},
|
||||
{ "iob": 0.327, "activity": 0.0048, "date": 1653156250000},
|
||||
{ "iob": 0.203, "activity": 0.0044, "date": 1653156549000},
|
||||
{ "iob": 0.132, "activity": 0.004, "date": 1653156849000},
|
||||
{ "iob": 0.064, "activity": 0.0034, "date": 1653157149000},
|
||||
{ "iob": -0.002, "activity": 0.0028, "date": 1653157449000},
|
||||
{ "iob": -0.064, "activity": 0.0022, "date": 1653157750000},
|
||||
{ "iob": -0.073, "activity": 0.0016, "date": 1653158049000},
|
||||
{ "iob": -0.08, "activity": 0.0011, "date": 1653158349000},
|
||||
{ "iob": -0.085, "activity": 0.0007, "date": 1653158649000},
|
||||
{ "iob": -0.087, "activity": 0.0004, "date": 1653158949000},
|
||||
{ "iob": -0.088, "activity": 0.0001, "date": 1653159249000},
|
||||
{ "iob": -0.088, "activity": -0.0001, "date": 1653159549000},
|
||||
{ "iob": -0.137, "activity": -0.0004, "date": 1653159849000},
|
||||
{ "iob": -0.184, "activity": -0.0007, "date": 1653160150000},
|
||||
{ "iob": -0.18, "activity": -0.001, "date": 1653160449000},
|
||||
{ "iob": -0.175, "activity": -0.0012, "date": 1653160749000},
|
||||
{ "iob": -0.168, "activity": -0.0014, "date": 1653161049000},
|
||||
{ "iob": -0.211, "activity": -0.0015, "date": 1653161350000},
|
||||
{ "iob": -0.203, "activity": -0.0017, "date": 1653161649000},
|
||||
{ "iob": -0.243, "activity": -0.002, "date": 1653161950000},
|
||||
{ "iob": -0.282, "activity": -0.0023, "date": 1653162250000},
|
||||
{ "iob": -0.32, "activity": -0.0026, "date": 1653162549000},
|
||||
{ "iob": -0.357, "activity": -0.0029, "date": 1653162850000},
|
||||
{ "iob": -0.391, "activity": -0.0032, "date": 1653163150000},
|
||||
{ "iob": -0.375, "activity": -0.0035, "date": 1653163449000},
|
||||
{ "iob": -0.357, "activity": -0.0036, "date": 1653163749000},
|
||||
{ "iob": -0.149, "activity": -0.0035, "date": 1653164049000},
|
||||
{ "iob": -0.132, "activity": -0.0031, "date": 1653164350000},
|
||||
{ "iob": 9.296, "activity": 0.015, "date": 1653164649000},
|
||||
{ "iob": 9.123, "activity": 0.0332, "date": 1653164950000},
|
||||
{ "iob": 8.96, "activity": 0.0474, "date": 1653165249000},
|
||||
{ "iob": 8.644, "activity": 0.0584, "date": 1653165550000},
|
||||
{ "iob": 8.282, "activity": 0.0664, "date": 1653165850000},
|
||||
{ "iob": 7.835, "activity": 0.0718, "date": 1653166149000},
|
||||
{ "iob": 7.416, "activity": 0.0753, "date": 1653166450000},
|
||||
{ "iob": 6.984, "activity": 0.0772, "date": 1653166749000},
|
||||
{ "iob": 6.547, "activity": 0.0776, "date": 1653167049000},
|
||||
{ "iob": 6.061, "activity": 0.0769, "date": 1653167350000},
|
||||
{ "iob": 5.68, "activity": 0.0754, "date": 1653167650000},
|
||||
{ "iob": 5.458, "activity": 0.0734, "date": 1653167949000},
|
||||
{ "iob": 5.046, "activity": 0.0712, "date": 1653168250000},
|
||||
{ "iob": 4.925, "activity": 0.069, "date": 1653168549000},
|
||||
{ "iob": 4.487, "activity": 0.0663, "date": 1653168849000},
|
||||
{ "iob": 4.113, "activity": 0.0633, "date": 1653169150000},
|
||||
{ "iob": 3.706, "activity": 0.0599, "date": 1653169449000},
|
||||
{ "iob": 3.363, "activity": 0.0566, "date": 1653169749000},
|
||||
{ "iob": 3.039, "activity": 0.053, "date": 1653170049000},
|
||||
{ "iob": 2.733, "activity": 0.0494, "date": 1653170350000},
|
||||
{ "iob": 2.395, "activity": 0.0457, "date": 1653170650000},
|
||||
{ "iob": 2.126, "activity": 0.0421, "date": 1653170950000},
|
||||
{ "iob": 1.824, "activity": 0.0385, "date": 1653171250000},
|
||||
{ "iob": 1.64, "activity": 0.0351, "date": 1653171549000},
|
||||
{ "iob": 1.473, "activity": 0.0319, "date": 1653171849000},
|
||||
{ "iob": 1.273, "activity": 0.0288, "date": 1653172150000},
|
||||
{ "iob": 1.136, "activity": 0.026, "date": 1653172450000},
|
||||
{ "iob": 1.011, "activity": 0.0235, "date": 1653172749000},
|
||||
{ "iob": 0.852, "activity": 0.021, "date": 1653173050000},
|
||||
{ "iob": 0.752, "activity": 0.0189, "date": 1653173350000},
|
||||
{ "iob": 0.662, "activity": 0.0169, "date": 1653173650000},
|
||||
{ "iob": 0.534, "activity": 0.0149, "date": 1653173949000},
|
||||
{ "iob": 0.463, "activity": 0.0132, "date": 1653174249000},
|
||||
{ "iob": 0.352, "activity": 0.0115, "date": 1653174550000},
|
||||
{ "iob": 0.298, "activity": 0.0101, "date": 1653174850000},
|
||||
{ "iob": 0.25, "activity": 0.0089, "date": 1653175149000},
|
||||
{ "iob": 0.329, "activity": 0.0079, "date": 1653175450000},
|
||||
{ "iob": 0.34, "activity": 0.0074, "date": 1653175750000},
|
||||
{ "iob": 0.304, "activity": 0.0068, "date": 1653176050000},
|
||||
{ "iob": 0.272, "activity": 0.0062, "date": 1653176350000},
|
||||
{ "iob": 0.512, "activity": 0.006, "date": 1653176650000},
|
||||
{ "iob": 0.581, "activity": 0.0061, "date": 1653176950000},
|
||||
{ "iob": 1.238, "activity": 0.0075, "date": 1653177250000},
|
||||
{ "iob": 1.147, "activity": 0.0088, "date": 1653177550000},
|
||||
{ "iob": 1.151, "activity": 0.0098, "date": 1653177850000},
|
||||
{ "iob": 1.05, "activity": 0.0104, "date": 1653178149000},
|
||||
{ "iob": 0.947, "activity": 0.0107, "date": 1653178449000},
|
||||
{ "iob": 0.844, "activity": 0.0106, "date": 1653178750000},
|
||||
{ "iob": 0.741, "activity": 0.0104, "date": 1653179050000},
|
||||
{ "iob": 0.59, "activity": 0.0099, "date": 1653179350000},
|
||||
{ "iob": 0.542, "activity": 0.0093, "date": 1653179649000},
|
||||
{ "iob": 0.497, "activity": 0.0087, "date": 1653179949000},
|
||||
{ "iob": 0.456, "activity": 0.0081, "date": 1653180250000},
|
||||
{ "iob": 0.516, "activity": 0.0077, "date": 1653180549000},
|
||||
{ "iob": 0.429, "activity": 0.0072, "date": 1653180849000},
|
||||
{ "iob": 0.294, "activity": 0.0066, "date": 1653181150000},
|
||||
{ "iob": 0.163, "activity": 0.0058, "date": 1653181450000},
|
||||
{ "iob": 0.037, "activity": 0.0049, "date": 1653181750000},
|
||||
{ "iob": -0.085, "activity": 0.0039, "date": 1653182050000},
|
||||
{ "iob": -0.153, "activity": 0.0029, "date": 1653182349000},
|
||||
{ "iob": -0.265, "activity": 0.0018, "date": 1653182650000},
|
||||
{ "iob": -0.371, "activity": 0.0007, "date": 1653182949000},
|
||||
{ "iob": -0.471, "activity": -0.0005, "date": 1653183249000},
|
||||
{ "iob": -0.566, "activity": -0.0016, "date": 1653183550000},
|
||||
{ "iob": -0.606, "activity": -0.0026, "date": 1653183850000},
|
||||
{ "iob": -0.64, "activity": -0.0036, "date": 1653184150000},
|
||||
{ "iob": -0.67, "activity": -0.0044, "date": 1653184450000}
|
||||
]
|
||||
|
Loading…
Reference in a new issue